santifer/career-ops · error · Error
Unsupported image type: ${extname(inputPath) || '(no extensi
Error message
Unsupported image type: ${extname(inputPath) || '(no extension)'}. Supported: ${Object.keys(MIME_TYPES).join(', ')} What it means
Thrown by convertImageToPdf() in img-to-pdf.mjs when detectMimeType() returns null because the file extension is not in the MIME_TYPES allowlist (.png, .jpg/.jpeg, .gif, .webp, .bmp, .svg). The message echoes the offending extension (or '(no extension)') and lists supported types so the caller knows exactly what to convert to.
Source
Thrown at img-to-pdf.mjs:107
console.log('');
console.log(' --force overwrite <output-path> if it already exists');
console.log('');
console.log('MVP scope: one image in, one PDF page out. Multi-image/multi-page is not supported.');
}
/**
* Render a single image file to a single-page PDF matching the image's own
* pixel dimensions (at 96 CSS px/inch), so the output is neither cropped
* nor padded with blank margins.
*
* @param {string} inputPath - Absolute path to the source image.
* @param {string} outputPath - Absolute path to write the PDF to.
* @returns {Promise<{outputPath: string, size: number, width: number, height: number}>}
*/
export async function convertImageToPdf(inputPath, outputPath) {
const mimeType = detectMimeType(inputPath);
if (!mimeType) {
throw new Error(`Unsupported image type: ${extname(inputPath) || '(no extension)'}. Supported: ${Object.keys(MIME_TYPES).join(', ')}`);
}
const buffer = await readFile(inputPath);
const base64 = buffer.toString('base64');
const html = `<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
* { margin: 0; padding: 0; }
html, body { margin: 0; padding: 0; }
img { display: block; }
</style>
</head>
<body>
<img id="career-ops-img" src="data:${mimeType};base64,${base64}">
</body>
</html>`;View on GitHub (pinned to 9b17a8ac97)
Solutions
- Convert the image to a supported format first: .png or .jpg — use `magick input.tiff output.png` or `sips -s format png input.heic --out output.png`.
- Rename to the correct extension if the file is actually a supported format but mislabeled (verify with `file input`).
- If SVG fails despite being listed, ensure it is well-formed XML (detectMimeType accepts .svg but rendering still requires valid markup).
- For .heic/.avif/.tiff, add an upstream conversion step to your pipeline rather than extending MIME_TYPES — Chromium rasterization of those is unreliable.
Example fix
// before
await convertImageToPdf('photo.heic', 'photo.pdf');
// throws: Unsupported image type: .heic
// after — convert first
// shell: magick photo.heic photo.png
await convertImageToPdf('photo.png', 'photo.pdf'); Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg']);
const ext = extname(inputPath).toLowerCase();
if (!SUPPORTED.has(ext)) {
throw new Error(`Pre-check: convert '${ext || 'no-ext'}' to PNG/JPEG before calling convertImageToPdf.`);
} Type guard
/** True if the path's extension is in img-to-pdf's MIME_TYPES allowlist. */
function isSupportedImage(path) {
const SUPPORTED = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg']);
return SUPPORTED.has(extname(path).toLowerCase());
} Prevention
- Convert HEIC/AVIF/TIFF to PNG upstream — do not extend MIME_TYPES for formats Chromium rasterizes poorly.
- Validate extension before invoking the pipeline; surface a clear pre-check error.
- Confirm the file's real type with `file` when extension looks wrong.
- Reject files with no extension early in the intake UI.
When it happens
Trigger: Passing an image with an unsupported or missing extension: .tiff, .heic, .avif, .pdf, .ico, or a file with no extension at all. detectMimeType keys off extname lowercased against MIME_TYPES, so case is handled but format is not.
Common situations: User drops a HEIC from an iPhone or a .tiff from a scanner into the pipeline; a screenshot saved as .avif by a newer browser; a recruiter's photo attached as a PDF renamed .jpg.
Related errors
- Unsupported profile photo format: ${photo} (expected PNG, JP
- CV section order diverges from cv.md: rendered ${renderedOrd
- Could not determine the rendered PDF page count (received ${
- Invalid page budget "${maxPages}". Use a positive integer.
- CV is ${pageCount} ${actualLabel}; the allowed maximum is ${
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/5c973f158623d05f.
Report an issue: GitHub.