{"record":{"id":"5c973f158623d05f","repo":"santifer/career-ops","slug":"unsupported-image-type-extname-inputpath","errorCode":null,"errorMessage":"Unsupported image type: ${extname(inputPath) || '(no extension)'}. Supported: ${Object.keys(MIME_TYPES).join(', ')}","messagePattern":"Unsupported image type: (.+?)\\. Supported: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"img-to-pdf.mjs","lineNumber":107,"sourceCode":"  console.log('');\n  console.log('  --force   overwrite <output-path> if it already exists');\n  console.log('');\n  console.log('MVP scope: one image in, one PDF page out. Multi-image/multi-page is not supported.');\n}\n\n/**\n * Render a single image file to a single-page PDF matching the image's own\n * pixel dimensions (at 96 CSS px/inch), so the output is neither cropped\n * nor padded with blank margins.\n *\n * @param {string} inputPath - Absolute path to the source image.\n * @param {string} outputPath - Absolute path to write the PDF to.\n * @returns {Promise<{outputPath: string, size: number, width: number, height: number}>}\n */\nexport async function convertImageToPdf(inputPath, outputPath) {\n  const mimeType = detectMimeType(inputPath);\n  if (!mimeType) {\n    throw new Error(`Unsupported image type: ${extname(inputPath) || '(no extension)'}. Supported: ${Object.keys(MIME_TYPES).join(', ')}`);\n  }\n\n  const buffer = await readFile(inputPath);\n  const base64 = buffer.toString('base64');\n  const html = `<!doctype html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<style>\n  * { margin: 0; padding: 0; }\n  html, body { margin: 0; padding: 0; }\n  img { display: block; }\n</style>\n</head>\n<body>\n<img id=\"career-ops-img\" src=\"data:${mimeType};base64,${base64}\">\n</body>\n</html>`;","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/img-to-pdf.mjs#L89-L125","documentation":"convertImageToPdf() first detects the image's MIME type from its file extension using the MIME_TYPES table. When the extension is absent or unsupported (png/jpeg/gif/webp-style set), detection returns null and the conversion is refused before any file read or Chromium launch.","triggerScenarios":"Calling convertImageToPdf() with a file whose extension is not in MIME_TYPES — e.g. .svg, .tiff, .bmp, .avif, .heic, or a file with no extension at all.","commonSituations":"Converting screenshots or exports in formats Chromium's <img> path wasn't configured for; extension-less temp files from downloads; camera RAW or HEIC phone photos.","solutions":["Convert the image to a supported format (e.g. with ImageMagick: `magick input.heic output.png`) and retry.","Rename the file so it carries a supported extension if the bytes are already in that format.","Check Object.keys(MIME_TYPES) in img-to-pdf.mjs for the exact supported extension list, and add the type there if it is genuinely renderable."],"exampleFix":"// before\nawait convertImageToPdf('photo.heic', 'photo.pdf');\n// after (pre-converted)\n// $ magick photo.heic photo.png\nawait convertImageToPdf('photo.png', 'photo.pdf');","handlingStrategy":"validation","validationCode":"import { extname } from 'node:path';\nconst SUPPORTED = ['.png', '.jpg', '.jpeg', '.gif', '.webp']; // match MIME_TYPES\nif (!SUPPORTED.includes(extname(inputPath).toLowerCase())) {\n  throw new Error(`convert ${inputPath} to a supported format first`);\n}","typeGuard":"const isSupportedImage = (p) => ['.png', '.jpg', '.jpeg', '.gif', '.webp'].includes(extname(p).toLowerCase());","tryCatchPattern":"try {\n  await convertImageToPdf(input, output);\n} catch (err) {\n  if (err.message.startsWith('Unsupported image type')) {\n    await exec(`magick ${input} ${input.replace(/\\.\\w+$/, '.png')}`);\n    return convertImageToPdf(input.replace(/\\.\\w+$/, '.png'), output);\n  }\n  throw err;\n}","preventionTips":["Normalize all images to PNG/JPEG before PDF conversion pipelines.","Ensure downloaded/converted files keep a proper extension.","Check the MIME_TYPES table for the current supported list."],"tags":["image","pdf","unsupported-format","validation"],"backgroundTag":"unsupported-operation","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}