{"record":{"id":"ca8e9e81e853c93a","repo":"BerriAI/litellm","slug":"either-file-data-or-file-id-must-be-present-in-the","errorCode":null,"errorMessage":"Either file_data or file_id must be present in the file message: {message}","messagePattern":"Either file_data or file_id must be present in the file message: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/prompt_templates/factory.py","lineNumber":1971,"sourceCode":"                    type=\"url\",\n                    url=file_id,\n                ),\n            )\n        elif content_block_type == \"image\":\n            return_block_param = AnthropicMessagesImageParam(\n                type=\"image\",\n                source=AnthropicContentParamSourceFileId(\n                    type=\"file\",\n                    file_id=file_id,\n                ),\n            )\n        elif content_block_type == \"container_upload\":\n            return_block_param = AnthropicMessagesContainerUploadParam(type=\"container_upload\", file_id=file_id)\n\n        if return_block_param is None:\n            raise Exception(f\"Unable to parse anthropic file message: {message}\")\n        return return_block_param\n    raise Exception(f\"Either file_data or file_id must be present in the file message: {message}\")\n\n\n_EMPTY_TEXT_PLACEHOLDER: Final = \"[System: Empty message content sanitised to satisfy protocol]\"\n\n\ndef _sanitize_empty_text_content(\n    message: AllMessageValues,\n) -> AllMessageValues:\n    \"\"\"\n    Case C: Sanitize empty text content\n    - Replace empty or whitespace-only text content with a placeholder message.\n    - Handles both string content and list-of-blocks content (rewriting only\n      the empty text blocks in place; non-text blocks like images are left\n      untouched).\n\n    Returns:\n        The message with sanitized content if needed, otherwise the original message\n    \"\"\"","sourceCodeStart":1953,"sourceCodeEnd":1989,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/litellm_core_utils/prompt_templates/factory.py#L1953-L1989","documentation":"The message has a file sub-object but it contains neither file_data nor file_id, so there is nothing to build an Anthropic block from. This is the outer raise (sibling of 794): it fires when the presence check for both keys fails, before any type-specific parsing.","triggerScenarios":"Sending a file message like {\"type\": \"file\", \"file\": {\"format\": \"pdf\"}} with both file_id and file_data absent or None.","commonSituations":"Building file blocks by hand; consuming file-upload APIs but forgetting to thread the returned id into the message.","solutions":["Provide file_id (Anthropic Files API id) or base64 file_data in the file sub-object","Validate file blocks before sending - see the type guard below"],"exampleFix":"# before\n{\"type\": \"file\", \"file\": {\"format\": \"pdf\"}}\n\n# after\n{\"type\": \"file\", \"file\": {\"file_data\": \"<base64>\", \"format\": \"pdf\"}}","handlingStrategy":"type-guard","validationCode":"def file_messages_have_source(messages: list[dict]) -> bool:\n    for m in messages:\n        content = m.get(\"content\")\n        if not isinstance(content, list):\n            continue\n        for block in content:\n            if isinstance(block, dict) and block.get(\"type\") == \"file\":\n                f = block.get(\"file\") or {}\n                if not (f.get(\"file_id\") or f.get(\"file_data\")):\n                    return False\n    return True","typeGuard":"from typing import Any, TypeGuard\n\ndef has_file_source(block: Any) -> TypeGuard[dict]:\n    \"\"\"True when a file block carries file_id or file_data.\"\"\"\n    if not isinstance(block, dict) or block.get(\"type\") != \"file\":\n        return True\n    f = block.get(\"file\")\n    return isinstance(f, dict) and bool(f.get(\"file_id\") or f.get(\"file_data\"))","tryCatchPattern":"try:\n    litellm.completion(model=\"anthropic/claude-...\", messages=messages)\nexcept Exception as e:\n    if \"Either file_data or file_id must be present\" in str(e):\n        # attach the uploaded file id (str(e) shows the message) and retry\n        messages = attach_file_sources(messages)\n    else:\n        raise","preventionTips":["Thread the Files API id into file.file_id immediately after upload","Centralize file-message construction with a required-source assertion","Validate inbound file blocks with a schema before they reach the LLM call"],"tags":["anthropic","file","validation","missing-field"],"backgroundTag":"missing-required-argument","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}