santifer/career-ops · error · Error
Unsupported profile photo data URL (expected base64 PNG, JPE
Error message
Unsupported profile photo data URL (expected base64 PNG, JPEG, WebP, or GIF)
What it means
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.
Source
Thrown at build-cv-html.mjs:124
}
async function prepareCandidatePhoto(candidate) {
const c = candidate && typeof candidate === 'object' ? { ...candidate } : {};
const photo = typeof c.photo === 'string' ? c.photo.trim() : '';
const style = c.photo_style || c.photoStyle || 'rounded';
if (!PHOTO_STYLES.has(style)) {
throw new Error(`Unsupported profile photo style: ${style} (expected rounded, circle, or square)`);
}
c.photo_style = style;
if (!photo) {
c.photo = '';
return c;
}
if (photo.startsWith('data:')) {
if (!IMAGE_DATA_URL_RE.test(photo)) {
throw new Error('Unsupported profile photo data URL (expected base64 PNG, JPEG, WebP, or GIF)');
}
c.photo = photo;
return c;
}
if (/^https?:\/\//i.test(photo)) {
c.photo = photo;
return c;
}
if (/^[a-z][a-z0-9+.-]+:/i.test(photo)) {
throw new Error(`Unsupported profile photo URL scheme: ${photo.split(':', 1)[0]}`);
}
const photoPath = isAbsolute(photo) ? photo : resolve(__dirname, photo);
const mime = PHOTO_MIME_BY_EXT.get(extname(photoPath).toLowerCase());
if (!mime) {
throw new Error(`Unsupported profile photo format: ${photo} (expected PNG, JPEG, WebP, or GIF)`);View on GitHub (pinned to 9b17a8ac97)
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).
Example fix
// before photo: 'data:image/svg+xml;base64,PHN2Zz4=' // throws // after — rasterize the SVG to PNG first, then photo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUg==...'
Defensive patterns
Strategy: validation
Validate before calling
const RE = /^data:image\/(?:png|jpeg|webp|gif);base64,[a-z0-9+\/=\s]+$/i;
function validDataUrl(u) {
if (!String(u).startsWith('data:')) return true; // not a data url — other path
if (!RE.test(u)) throw new Error('Use data:image/(png|jpeg|webp|gif);base64,<body>');
return u;
} Type guard
function isAcceptableDataUrl(u) {
return /^data:image\/(?:png|jpeg|webp|gif);base64,[a-z0-9+\/=\s]+$/i.test(String(u));
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unsupported profile photo URL scheme: ${photo.split(':', 1)[
- Unsupported profile photo style: ${style} (expected rounded,
- Unsupported profile photo format: ${photo} (expected PNG, JP
- Access denied: Egress guard blocked private target IP ${ip}
- apify: invalid actorId ${JSON.stringify(actorId)}. Expected
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/b8329af0d8b69168.
Report an issue: GitHub.