{"record":{"id":"460c9efaa2f91504","repo":"rohitg00/ai-engineering-from-scratch","slug":"image-bytes-must-not-be-empty","errorCode":null,"errorMessage":"image_bytes must not be empty","messagePattern":"image_bytes must not be empty","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"certifications/claude/lessons/08-messages-api-and-application-lifecycle/code/main.py","lineNumber":198,"sourceCode":"        raise ValueError(\"batch size must be positive\")\n    return [items[index : index + size] for index in range(0, len(items), size)]\n\n\ndef stable_cache_key(model: str, stable_prefix: str) -> str:\n    payload = f\"{model}\\0{stable_prefix}\".encode(\"utf-8\")\n    return hashlib.sha256(payload).hexdigest()\n\n\nIMAGE_MEDIA_TYPES = {\"image/jpeg\", \"image/png\", \"image/gif\", \"image/webp\"}\nDOCUMENT_MEDIA_TYPES = {\"application/pdf\", \"text/plain\"}\n\n\ndef build_multimodal_request(prompt: str, image_bytes: bytes, reusable_file_id: str) -> dict[str, Any]:\n    \"\"\"Build an offline request body with inline vision and a reusable file asset.\"\"\"\n    if not prompt.strip():\n        raise ValueError(\"prompt must not be empty\")\n    if not image_bytes:\n        raise ValueError(\"image_bytes must not be empty\")\n    if not reusable_file_id.strip():\n        raise ValueError(\"reusable_file_id must not be empty\")\n    return {\n        \"model\": \"<current-model-id>\",\n        \"max_tokens\": 400,\n        \"messages\": [\n            {\n                \"role\": \"user\",\n                \"content\": [\n                    {\"type\": \"text\", \"text\": prompt},\n                    {\n                        \"type\": \"image\",\n                        \"source\": {\n                            \"type\": \"base64\",\n                            \"media_type\": \"image/png\",\n                            \"data\": base64.b64encode(image_bytes).decode(\"ascii\"),\n                        },\n                    },","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/rohitg00/ai-engineering-from-scratch/blob/39ea8a1c6d0b61f071226eff7ede4d4105fed820/certifications/claude/lessons/08-messages-api-and-application-lifecycle/code/main.py#L180-L216","documentation":"Raised by build_multimodal_request when image_bytes is empty. An image content block requires actual bytes; an empty payload would produce a request the real API rejects, so the builder fails fast offline (multimodal_lab_fixture).","triggerScenarios":"Calling build_multimodal_request('prompt', b'', 'file_1') after a file read returned empty bytes or a download saved nothing.","commonSituations":"Reading a 0-byte file, a failed upload/download that returns empty bytes without raising, or a test fixture reading the wrong path.","solutions":["Verify the file size is greater than 0 before reading or calling","Check the upstream fetch returned a non-empty body and raise on empty","Log byte counts when ingesting images to catch empty captures early"],"exampleFix":"# before\ndata = path.read_bytes()  # 0-byte file slips through\nbuild_multimodal_request(prompt, data, file_id)\n# after\ndata = path.read_bytes()\nif not data:\n    raise ValueError(f\"empty image file: {path}\")\nbuild_multimodal_request(prompt, data, file_id)","handlingStrategy":"validation","validationCode":"if not image_bytes:\n    raise ValueError(\"image file is empty\")\nreq = build_multimodal_request(prompt, image_bytes, file_id)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check file size > 0 before reading","Treat empty download bodies as errors at the fetch layer"],"tags":["vision","multimodal","empty-payload","python"],"backgroundTag":"empty-request-body","analyzedSha":"39ea8a1c6d0b61f071226eff7ede4d4105fed820","analyzedAt":"2026-08-26T03:13:46.626Z","schemaVersion":2},"datasetVersion":"2026-08-26T07:17:17.940Z"}