{"record":{"id":"4066cf0b4dd653f8","repo":"BerriAI/litellm","slug":"bedrock-converse-only-supports-base64-encoded-docu","errorCode":null,"errorMessage":"Bedrock Converse only supports base64-encoded document sources, got '{source_type}'. Please convert the document to base64 before sending to Bedrock.","messagePattern":"Bedrock Converse only supports base64-encoded document sources, got '(.+?)'\\. Please convert the document to base64 before sending to Bedrock\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/prompt_templates/factory.py","lineNumber":4645,"sourceCode":"        if file_data is None and file_id is None:\n            raise litellm.BadRequestError(\n                message=f\"file_data and file_id cannot both be None. Got={message}\",\n                model=\"\",\n                llm_provider=\"bedrock\",\n            )\n        return await BedrockImageProcessor.process_image_async(image_url=cast(str, file_id or file_data), format=format)\n\n    @staticmethod\n    def _process_document_message(element: dict) -> BedrockContentBlock:\n        \"\"\"Convert a document content block to a Bedrock DocumentBlock.\n\n        Handles the Anthropic-style document format:\n        {\"type\": \"document\", \"source\": {\"type\": \"base64\", \"media_type\": \"application/pdf\", \"data\": \"...\"}}\n        \"\"\"\n        source: Final = element[\"source\"]\n        source_type: Final = source.get(\"type\")\n        if source_type != \"base64\":\n            raise ValueError(\n                f\"Bedrock Converse only supports base64-encoded document sources, got '{source_type}'. \"\n                \"Please convert the document to base64 before sending to Bedrock.\"\n            )\n        media_type: Final[str] = source[\"media_type\"]\n        data: Final[str] = source[\"data\"]\n        doc_format = BedrockImageProcessor._validate_format(mime_type=media_type, image_format=media_type.split(\"/\")[1])\n\n        # Deterministic name using the same hashing pattern as _create_bedrock_block\n        HASH_SAMPLE_BYTES: Final = 64 * 1024\n        normalized: Final = \"\".join(data.split()).encode(\"utf-8\")\n        sample: Final = normalized[:HASH_SAMPLE_BYTES]\n        hasher: Final = hashlib.sha256()\n        hasher.update(sample)\n        hasher.update(str(len(normalized)).encode(\"utf-8\"))\n        content_hash: Final = hasher.hexdigest()[:16]\n        document_name: Final = f\"Document_{content_hash}_{doc_format}\"\n\n        return BedrockContentBlock(","sourceCodeStart":4627,"sourceCodeEnd":4663,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/prompt_templates/factory.py#L4627-L4663","documentation":"Bedrock Converse's document ingestion (_process_document_message) only accepts Anthropic-style sources with source.type == 'base64'. A document block whose source type is 'url', 'file', or anything else raises this ValueError telling you to base64-encode the document.","triggerScenarios":"Sending {\"type\": \"document\", \"source\": {\"type\": \"url\", \"url\": ...}} (valid for some Anthropic endpoints) to a bedrock/... model; or a source dict missing/typoing the 'type' key (source_type None).","commonSituations":"Sharing the same PDF message payload between Anthropic direct and Bedrock routes; copy-pasting Anthropic docs examples; source dicts built dynamically where 'type' is omitted.","solutions":["Fetch the document (PDF/TXT/MD/DOCX) and inline it: source = {\"type\": \"base64\", \"media_type\": \"application/pdf\", \"data\": <b64>}.","For Anthropic-style URLs, download and encode before the call when targeting Bedrock.","Check media_type is a supported Bedrock format (pdf, txt, md, docx, xlsx, csv)."],"exampleFix":"# before\n{\"type\": \"document\", \"source\": {\"type\": \"url\", \"url\": \"https://x/report.pdf\"}}\n# after\nimport base64, requests\ndata = base64.b64encode(requests.get(\"https://x/report.pdf\").content).decode()\n{\"type\": \"document\", \"source\": {\"type\": \"base64\", \"media_type\": \"application/pdf\", \"data\": data}}","handlingStrategy":"validation","validationCode":"def to_bedrock_document(url: str, media_type: str = \"application/pdf\") -> dict:\n    data = base64.b64encode(requests.get(url, timeout=60).content).decode()\n    return {\"type\": \"document\", \"source\": {\"type\": \"base64\", \"media_type\": media_type, \"data\": data}}","typeGuard":"def is_bedrock_doc_source(source) -> bool:\n    return isinstance(source, dict) and source.get(\"type\") == \"base64\" and \"data\" in source and \"media_type\" in source","tryCatchPattern":"try:\n    resp = litellm.completion(model=\"bedrock/...\", messages=msgs)\nexcept ValueError as e:\n    if \"only supports base64-encoded document sources\" in str(e):\n        msgs = rebuild_docs_as_base64(msgs)\n        resp = litellm.completion(model=\"bedrock/...\", messages=msgs)","preventionTips":["Route Anthropic-style url documents through a download-and-encode step when targeting Bedrock.","Keep one document-message builder per provider instead of a shared payload."],"tags":["bedrock","document","pdf","multimodal"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}