{"record":{"id":"b8329af0d8b69168","repo":"santifer/career-ops","slug":"unsupported-profile-photo-data-url-expected-base6","errorCode":null,"errorMessage":"Unsupported profile photo data URL (expected base64 PNG, JPEG, WebP, or GIF)","messagePattern":"Unsupported profile photo data URL \\(expected base64 PNG, JPEG, WebP, or GIF\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"build-cv-html.mjs","lineNumber":124,"sourceCode":"}\n\nasync function prepareCandidatePhoto(candidate) {\n  const c = candidate && typeof candidate === 'object' ? { ...candidate } : {};\n  const photo = typeof c.photo === 'string' ? c.photo.trim() : '';\n  const style = c.photo_style || c.photoStyle || 'rounded';\n\n  if (!PHOTO_STYLES.has(style)) {\n    throw new Error(`Unsupported profile photo style: ${style} (expected rounded, circle, or square)`);\n  }\n  c.photo_style = style;\n  if (!photo) {\n    c.photo = '';\n    return c;\n  }\n\n  if (photo.startsWith('data:')) {\n    if (!IMAGE_DATA_URL_RE.test(photo)) {\n      throw new Error('Unsupported profile photo data URL (expected base64 PNG, JPEG, WebP, or GIF)');\n    }\n    c.photo = photo;\n    return c;\n  }\n\n  if (/^https?:\\/\\//i.test(photo)) {\n    c.photo = photo;\n    return c;\n  }\n\n  if (/^[a-z][a-z0-9+.-]+:/i.test(photo)) {\n    throw new Error(`Unsupported profile photo URL scheme: ${photo.split(':', 1)[0]}`);\n  }\n\n  const photoPath = isAbsolute(photo) ? photo : resolve(__dirname, photo);\n  const mime = PHOTO_MIME_BY_EXT.get(extname(photoPath).toLowerCase());\n  if (!mime) {\n    throw new Error(`Unsupported profile photo format: ${photo} (expected PNG, JPEG, WebP, or GIF)`);","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/build-cv-html.mjs#L106-L142","documentation":"Validation in `prepareCandidatePhoto`: when `photo` starts with `data:` it must fully match `IMAGE_DATA_URL_RE` = `/^data:image\\/(?:png|jpeg|webp|gif);base64,[a-z0-9+\\/=\\s]+$/i`. This requires the `image/<mime>` subtype, explicit `;base64`, and valid base64 body. Malformed data URLs are rejected to avoid embedding broken/unsafe content in the CV HTML.","triggerScenarios":"Passing `data:image/svg+xml;base64,...` (svg not allowed), `data:image/png;base64,` (empty body), a data URL with `;charset=` or other params interleaved, missing `;base64`, a URL-encoded (`%2F`) data URL, or a truncated/corrupted base64 string with invalid chars.","commonSituations":"User uploads SVG (common for logos/avatars); tool emits a URL-encoded data URL; base64 string accidentally truncated in transit; mime labels like `image/jpg` instead of `image/jpeg`; data URL with extra whitespace/newlines outside the allowed set.","solutions":["Use one of the four allowed mimes: `image/png`, `image/jpeg`, `image/webp`, `image/gif`, with `;base64,` and a valid base64 body.","For SVG, rasterize first (PNG/WEBP) or extend `IMAGE_DATA_URL_RE` and add the mime intentionally.","Use `image/jpeg` (not `image/jpg`).","Strip any internal whitespace/newlines from the base64 body before embedding, or rely on the regex's tolerated `\\s`.","If you have a raw file path instead, pass the path (the function resolves and embeds it)."],"exampleFix":"// before\nphoto: 'data:image/svg+xml;base64,PHN2Zz4=' // throws\n// after — rasterize the SVG to PNG first, then\nphoto: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUg==...'","handlingStrategy":"validation","validationCode":"const RE = /^data:image\\/(?:png|jpeg|webp|gif);base64,[a-z0-9+\\/=\\s]+$/i;\nfunction validDataUrl(u) {\n  if (!String(u).startsWith('data:')) return true; // not a data url — other path\n  if (!RE.test(u)) throw new Error('Use data:image/(png|jpeg|webp|gif);base64,<body>');\n  return u;\n}","typeGuard":"function isAcceptableDataUrl(u) {\n  return /^data:image\\/(?:png|jpeg|webp|gif);base64,[a-z0-9+\\/=\\s]+$/i.test(String(u));\n}","tryCatchPattern":null,"preventionTips":["Restrict to png/jpeg/webp/gif data URLs with explicit `;base64,`.","Rasterize SVG to PNG/WEBP before embedding.","Use `image/jpeg` (not `image/jpg`).","Pass a local file path or http(s) URL if your asset isn't already a data URL."],"tags":["validation","photo","data-url","build-cv-html","security"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}