{"record":{"id":"3a233217f63b5fc5","repo":"linshenkx/prompt-optimizer","slug":"failed-to-decode-image-data-url-payload","errorCode":null,"errorMessage":"Failed to decode image data URL payload","messagePattern":"Failed to decode image data URL payload","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/utils/image-asset-storage.ts","lineNumber":122,"sourceCode":"    return { b64, mimeType: finalMimeType }\n  }\n\n  if (typeof FileReader === 'undefined') {\n    throw new Error('FileReader is not available to decode image payload')\n  }\n\n  const blob = new Blob([ab], { type: finalMimeType })\n\n  const dataUrl = await new Promise<string>((resolve, reject) => {\n    const reader = new FileReader()\n    reader.onerror = () => reject(new Error('Failed to read image blob'))\n    reader.onload = () => resolve(String(reader.result || ''))\n    reader.readAsDataURL(blob)\n  })\n\n  const parsed = parseDataUrlPayload(dataUrl)\n  if (!parsed?.b64) {\n    throw new Error('Failed to decode image data URL payload')\n  }\n\n  return {\n    b64: parsed.b64,\n    mimeType: parsed.mimeType || finalMimeType,\n  }\n}\n\nexport const normalizeImageSourceToPayload = async (\n  source: string,\n): Promise<ImagePayload | null> => {\n  const raw = String(source || '').trim()\n  if (!raw) return null\n\n  const dataUrlPayload = parseDataUrlPayload(raw)\n  if (dataUrlPayload) return dataUrlPayload\n\n  if (/^https?:\\/\\//u.test(raw)) {","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/utils/image-asset-storage.ts#L104-L140","documentation":"After FileReader.readAsDataURL produces a data URL, parseDataUrlPayload extracts the base64 and MIME parts. If parsing yields no b64 component the function throws, meaning the data URL was malformed (empty result, missing comma, unparsable header) and the payload could not be recovered.","triggerScenarios":"FileReader resolves with an empty or non-standard result string (e.g. '' from a zero-byte blob), a data URL without the 'data:...;base64,' structure, or readAsDataURL returning a plain-URL result for unusual MIME types; parseDataUrlPayload then returns null/empty and the guard fires.","commonSituations":"Zero-byte responses from a failing server with 200 status; exotic MIME types where the browser emits a non-standard data URL; reader.result being unexpectedly coerced (String(reader.result || '') masking undefined); custom FileReader polyfills emitting wrong formats.","solutions":["Inspect the fetched response: log content-type and byte length; a 200 with empty body commonly causes this","Validate bytes.length > 0 before requesting payload conversion","If using a FileReader polyfill, ensure it emits standard 'data:<mime>;base64,<data>' output","Fall back to Buffer/btoa-based encoding when the data URL path fails"],"exampleFix":"// before\nconst payload = await normalizeImageSourceToPayload(url) // empty 200 body -> throws\n\n// after\nconst resp = await fetch(url)\nif (!resp.ok || (await resp.clone().arrayBuffer()).byteLength === 0) {\n  throw new Error('Empty image response')\n}\nconst payload = await normalizeImageSourceToPayload(url)","handlingStrategy":"validation","validationCode":"const resp = await fetch(url)\nconst ab = await resp.arrayBuffer()\nif (ab.byteLength === 0) throw new Error('Empty image response')\n// only then hand off to payload normalization","typeGuard":"const isWellFormedDataUrl = (s: string): boolean =>\n  /^data:[\\w./+-]+;base64,[A-Za-z0-9+/]+={0,2}$/.test(s)","tryCatchPattern":"try { await fetchImagePayloadFromUrl(url) } catch (e) { if (e.message === 'Failed to decode image data URL payload') { /* check empty body / polyfill, retry with btoa path */ } else throw e }","preventionTips":["Treat 200-with-empty-body as an error before decoding","Validate data URL shape after readAsDataURL","Ensure FileReader polyfills emit standard base64 data URLs"],"tags":["data-url","base64","filereader","parsing"],"backgroundTag":"malformed-data-url","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}