santifer/career-ops · error · Error
Image failed to decode within 10s (unreadable or corrupt fil
Error message
Image failed to decode within 10s (unreadable or corrupt file?): ${inputPath} What it means
Thrown by convertImageToPdf() in img-to-pdf.mjs when the in-page <img> did not reach naturalWidth>0 && naturalHeight>0 && complete within a 10-second Playwright waitForFunction. This means Chromium could load the HTML shell but the embedded base64 image never decoded — almost always a corrupt, truncated, or zero-byte source file rather than a slow network (the image is inline base64, so there is no network).
Source
Thrown at img-to-pdf.mjs:140
<body>
<img id="career-ops-img" src="data:${mimeType};base64,${base64}">
</body>
</html>`;
await mkdir(dirname(outputPath), { recursive: true });
const browser = await chromium.launch({ headless: true });
try {
const page = await browser.newPage();
await page.setContent(html, { waitUntil: 'load' });
try {
await page.waitForFunction(() => {
const img = document.getElementById('career-ops-img');
return !!img && img.complete && img.naturalWidth > 0 && img.naturalHeight > 0;
}, { timeout: 10000 });
} catch (err) {
throw new Error(`Image failed to decode within 10s (unreadable or corrupt file?): ${inputPath}`);
}
const { width, height } = await page.evaluate(() => {
const img = document.getElementById('career-ops-img');
return { width: img.naturalWidth, height: img.naturalHeight };
});
// 96 CSS px per inch is the standard browser/Playwright conversion —
// sizing the PDF page to the image's own dimensions means the image
// fills the page exactly: no cropping, no blank margins.
const widthIn = width / 96;
const heightIn = height / 96;
const pdfBuffer = await page.pdf({
width: `${widthIn}in`,
height: `${heightIn}in`,
margin: { top: '0', right: '0', bottom: '0', left: '0' },
printBackground: true,View on GitHub (pinned to 9b17a8ac97)
Solutions
- Open the source image in a normal viewer to confirm it decodes — if it doesn't, re-download or re-export the original.
- Check the file is not zero-byte: `ls -l input.png` and `file input.png` to confirm type matches extension.
- For SVGs, validate the XML: `xmllint --noout input.svg`.
- Re-export from the source application (Photoshop/Figma/etc.) to a fresh PNG/JPEG.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate the file is non-empty and decodable-ish before Chromium
const stat = await fsPromises.stat(inputPath);
if (stat.size === 0) throw new Error('Image file is zero bytes: ' + inputPath); Try / catch
try {
return await convertImageToPdf(inputPath, outputPath);
} catch (e) {
if (e.message.includes('failed to decode within 10s')) {
// almost always corrupt/truncated source; re-export from original
throw new Error(`Image appears corrupt: ${inputPath}. Re-export the original as PNG/JPEG.`);
}
throw e;
} Prevention
- Confirm the source image opens in a viewer before piping it through the converter.
- Check file size > 0 and `file` output matches extension as a cheap pre-check.
- Validate SVGs with xmllint before conversion.
- Re-export from the source app if a file is suspect.
When it happens
Trigger: The source file is truncated (download interrupted), zero-byte, a valid extension but wrong contents (e.g. a .png that is actually HTML), or a degenerate image Chromium's decoder rejects. waitForFunction times out at 10000ms and the catch rethrows this message.
Common situations: Partially downloaded image; a file renamed from another format; an SVG with invalid XML that Chromium cannot rasterize; a corrupt BMP/GIF; disk read returned short.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${msg}
- Could not determine the rendered PDF page count (received ${
- Could not determine the rendered PDF page count from its pag
- Unsupported image type: ${extname(inputPath) || '(no extensi
- The apply feature needs Google Chrome. Install Chrome (or ru
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/7dc81207805e47f5.
Report an issue: GitHub.