{"record":{"id":"1895413614debe3c","repo":"can1357/oh-my-pi","slug":"image-data-is-empty","errorCode":null,"errorMessage":"Image data is empty.","messagePattern":"Image data is empty\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/image-gen.ts","lineNumber":389,"sourceCode":"\treturn model.includes(\"/\") ? model : `google/${model}`;\n}\n\nfunction toDataUrl(image: InlineImageData): string {\n\treturn `data:${image.mimeType};base64,${image.data}`;\n}\n\nasync function loadImageFromUrl(\n\timageUrl: string,\n\tfetchImpl: FetchImpl,\n\tsignal?: AbortSignal,\n): Promise<InlineImageData> {\n\tif (imageUrl.startsWith(\"data:\")) {\n\t\tconst normalized = normalizeDataUrl(imageUrl.trim());\n\t\tif (!normalized.mimeType) {\n\t\t\tthrow new Error(\"mime_type is required when providing raw base64 data.\");\n\t\t}\n\t\tif (!normalized.data) {\n\t\t\tthrow new Error(\"Image data is empty.\");\n\t\t}\n\t\treturn { data: normalized.data, mimeType: normalized.mimeType };\n\t}\n\n\tconst response = await fetchImpl(imageUrl, { signal });\n\tif (!response.ok) {\n\t\tconst rawText = await response.text();\n\t\tthrow new Error(`Image download failed (${response.status}): ${rawText}`);\n\t}\n\tconst contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n\tif (!contentType?.startsWith(\"image/\")) {\n\t\tthrow new Error(`Unsupported image type from URL: ${imageUrl}`);\n\t}\n\tconst buffer = await response.bytes();\n\treturn { data: buffer.toBase64(), mimeType: contentType };\n}\n\nfunction collectOpenRouterResponseText(message: OpenRouterMessage | undefined): string | undefined {","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/image-gen.ts#L371-L407","documentation":"For a data: URL whose mime type parsed correctly, the base64 payload portion must still be non-empty; normalizeDataUrl returning empty data means the URL contained a header but no (or only empty) base64 payload. The tool throws to avoid sending an inline image with zero bytes, which upstream providers reject. It is a client-side validation of malformed inline image input.","triggerScenarios":"Calling image generation with `data:image/png;base64,` (trailing comma, empty payload) or a data URL whose payload was lost during string construction/interpolation.","commonSituations":"Template variables that failed to fill in the base64 string; truncation from config limits or copy-paste; encoders producing empty output for empty input buffers.","solutions":["Verify the data URL actually contains base64 data after the comma","Re-generate the base64 encoding from the source file (e.g. `base64 -w0 image.png` or `Bun.file(path).base64()`)","Fall back to passing a file path instead of an inline data URL","Log the data-URL length before the call to catch empty payloads early"],"exampleFix":"// before\nconst url = `data:image/png;base64,${b64}`; // b64 was \"\"\n// after\nconst b64 = Bun.file(\"logo.png\").base64();\nif (!b64) throw new Error(\"source image is empty\");\nconst url = `data:image/png;base64,${b64}`;","handlingStrategy":"validation","validationCode":"function validateDataUrlPayload(url: string): boolean {\n\tconst idx = url.indexOf(\",\");\n\treturn idx !== -1 && url.length > idx + 1 && /^[A-Za-z0-9+/=\\s]+$/.test(url.slice(idx + 1));\n}","typeGuard":null,"tryCatchPattern":"try {\n\tawait genImage({ image: dataUrl });\n} catch (err) {\n\tif (err instanceof Error && err.message === \"Image data is empty.\") {\n\t\t// re-encode from source and retry once\n\t}\n\tthrow err;\n}","preventionTips":["Check data URL length > mime header length before calling","Generate base64 with Bun.file(path).base64() rather than manual encoding","Log payload length in debug output for image pipelines","Guard template interpolations that could resolve to \"\""],"tags":["validation","data-url","empty-payload","image-generation"],"backgroundTag":"empty-image-payload","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}