{"record":{"id":"b000c8557fe0dd3b","repo":"HKUDS/DeepTutor","slug":"malformed-image-data-uri","errorCode":null,"errorMessage":"Malformed image data URI.","messagePattern":"Malformed image data URI\\.","errorType":"validation","errorClass":"GenerationProviderError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/imagegen/adapters/chat_completions.py","lineNumber":103,"sourceCode":"                    sources.append(src)\n            # Fallback: some variants nest images in the content parts array.\n            content = message.get(\"content\")\n            if isinstance(content, list):\n                for part in content:\n                    if not isinstance(part, dict):\n                        continue\n                    src = (part.get(\"image_url\") or {}).get(\"url\") or part.get(\"url\")\n                    if isinstance(src, str) and src.startswith((\"data:image\", \"http\")):\n                        sources.append(src)\n        if not sources:\n            raise GenerationProviderError(\"Image response had no image in the assistant message.\")\n        return sources\n\n    async def _materialize(self, client: httpx.AsyncClient, src: str) -> tuple[bytes, str]:\n        if src.startswith(\"data:\"):\n            header, _, encoded = src.partition(\",\")\n            if not encoded:\n                raise GenerationProviderError(\"Malformed image data URI.\")\n            content_type = header[5:].split(\";\", 1)[0].strip() or \"image/png\"\n            return base64.b64decode(encoded), content_type\n        resp = await client.get(src)\n        raise_for_provider(resp, \"Image download\")\n        content_type = resp.headers.get(\"content-type\") or \"image/png\"\n        if not content_type.startswith(\"image/\"):\n            content_type = \"image/png\"\n        return resp.content, content_type\n\n\n__all__ = [\"ChatCompletionsImagegenAdapter\"]\n","sourceCodeStart":85,"sourceCodeEnd":115,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/imagegen/adapters/chat_completions.py#L85-L115","documentation":"_materialize received a data: URI whose payload after the comma is empty (src.partition(',') yielded nothing), so base64 decoding is impossible. The header exists but the base64 image body is missing or truncated before the comma.","triggerScenarios":"A content part with url like \"data:image/png;base64,\" (empty payload), or a malformed URI where the image bytes were dropped/truncated in transit or by the provider.","commonSituations":"Provider bug or truncation when inlining images; intermediary proxy stripping large bodies; model emitting a placeholder data URI.","solutions":["Retry the generation — transient truncation from the provider is the most common cause","Log the offending src string length to confirm it's empty vs truncated","If reproducible with one model/provider, report or switch providers/adapters"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def valid_data_uri(src: str) -> bool:\n    return src.startswith(\"data:\") and len(src.partition(\",\")[2]) > 0","typeGuard":null,"tryCatchPattern":"try:\n    img = await adapter._materialize(client, src)\nexcept GenerationProviderError as exc:\n    if \"Malformed image data URI\" in str(exc):\n        continue  # skip bad part, try next source","preventionTips":["Validate data URIs before decoding when handling raw provider payloads","Treat empty-payload data URIs as transient and retry generation"],"tags":["imagegen","data-uri","base64","malformed-payload"],"backgroundTag":"malformed-data-uri","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}