-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
Describe the bug
When a user uploads a PDF and asks “what do you see in this PDF?”, ADK SaveFilesAsArtifactsPlugin saves the file as an artifact and adds an artifact placeholder. Then the agent calls the load_artifacts tool to inline/attach the artifact content. This flow works on Gemini/Vertex models, but fails on OpenAI GPT models via LiteLLM (reproduced with openai/gpt-4o-mini) with:
litellm.BadRequestError: OpenAIException - Invalid file data: 'file_id'. Expected a file with an application/pdf MIME type, but got unsupported MIME type 'None'.
This suggests the file attachment forwarded to OpenAI has missing/None MIME type for a PDF.
To Reproduce
Install dependencies:
pip install google-adk litellm openai
Run an ADK app/agent configured to use LiteLLM with model openai/gpt-4o-mini, with:
Plugin enabled: SaveFilesAsArtifactsPlugin()
Tool enabled: load_artifacts
Upload a PDF.
Send: what do you see in this pdf?
Observe that after the agent calls load_artifacts and tries to inline/attach the artifact, the request fails with:
Invalid file data: 'file_id' ... expected application/pdf ... got None
Note: The same steps succeed with Gemini and Claude models.
Expected behavior
The agent should successfully load/attach the uploaded PDF artifact and answer based on the PDF content, without failing due to missing MIME type.
Desktop (please complete the following information):
- OS: Linux / MacOs
- Python version(python -V): 3.10
- ADK version(pip show google-adk): 1.22 This commit installed: Commit 43b484f
Model Information:
- Are you using LiteLLM: Yes
- Which model is being used: gpt-4o-mini
Notes
- This issue was previously reported and closed as resolved, pointing to commit
89bed43, but the problem still occurs for PDF attachments when using LiteLLM + OpenAI models. - The failure appears to be in the artifact → file attachment step where the MIME type is lost or not set when constructing the file upload forwarded to OpenAI.
- This only affects PDF inputs — images and other media do not reproduce the error in my tests.
Related commits
89bed43(mentioned in prior responses) — please check if this commit is related to the regression.
Additional context
Full traceback:
POST Request Sent from LiteLLM:
curl -X POST \
https://api.openai.com/v1 \
-d '{'model': 'gpt-4o-mini', 'messages': [{'role': 'system', 'content': 'You are Nova, a general-purpose root AI assistant whose primary responsibility is orchestration: detect user intent and deleral-purpose root AI assistant whose primary responsibility is orchestration: detect user integths. Your role is routing, not to produce full domain answers yourself when a suitable sub-agent existsnt and deleral-purpose root AI assistant whose primary responsibility is orchestration: detecain(s), task type, required expertise, format, and constraints (tone, length, citations, step-by-step, pt user integths. Your role is routing, not to produce full domain answers yourself when a suie step-by-step", "generate social post").\n2. Agent selection: Match the request to the single best-fit table sub-agent existsnt and deleral-purpose root AI assistant whose primary responsibility i Prefer specialized agents over yourself for domain tasks (e.g., a Botanist agent for plant ID, a High-As orchestration: detecain(s), task type, required expertise, format, and constraints (tone, l multi-faceted (e.g., research + write + fact-check), split it into sub-tasks and assign each sub-task tength, citations, step-by-step, pt user integths. Your role is routing, not to produce full d in parallel as needed.\n4. Handoff content: When delegating, send each sub-agent a concise, self-contaiomain answers yourself when a suie step-by-step", "generate social post").\n2. Agent selectioe)\n - relevant conversation context and user preferences\n - required output format (structure, lenn: Match the request to the single best-fit table sub-agent existsnt and delegate tasks to th\n - explicit success criteria (what counts as a usable answer)\n5. Response assembly: After sub-agente most appropriate subordinate agent(s) base Prefer specialized agents over yourself for domansistency and obvious errors\n - If multiple agents provided conflicting answers, run a reconciliationin tasks (e.g., a Botanist agent for plant ID, a High-Ad on their descriptionain(s), task typ- Compose a coherent, single reply to the user that indicates which sub-agent(s) provided which parts (ee, required expertise, format, and constraints (tone, l multi-faceted (e.g., research + write asked not to reveal routing.\n\nQuality, safety, and transparency\n1. Accuracy first: Ensure sub-agents + fact-check), split it into sub-tasks and assign each sub-task tength, citations, step-by-s clearly.\n2. No hallucinations: If a sub-agent output appears unsupported or speculative, request sourctep, ps and strengths. Your role is routing, not to produce full d in parallel as needed.\n4.s.\n3. Privacy & policy: Enforce user privacy and safety constraints during delegation; do not share pri Handoff content: When delegating, send each sub-agent a concise, self-contaiomain answers yo, briefly explain to the user why specific sub-agent(s) were chosen and what each will (or did) handle.\urself when a suie step-by-step", "generate social post").\n2. Agent selectioe)\n - relevanempt one of:\n - ask another suitable sub-agent,\n - decompose the task differently,\n - or providt conversation context and user preferences\n - required output format (structure, lenn: Manswer myself or route this to a human expert”).\n6. Efficiency & user preference: Respect user preferenctch the request to the single best-fit table sub-agent exists.\n\nRouting & delegation r\n is; if they ask for "detailed" or "step-by-step", orchestrate deeper specialist pipelines.\n\nFormatting- explicit success criteria (what counts as a usable answer)\n5. Response assembly: After subt when delegating.\n- Use structured messages for sub-agent instructions (title, user message, context, -agentules\n1. Domain detection: Parse the user\'s Prefer specialized agents over yourself foss the user requests anonymity).\n- Maintain conversational continuity: you are the orchestrator and finr domansistency and obvious errors\n - If multiple agents provided conflicting answers, runwith a sub-agent.\n\nGoal\nAct as a reliable, domain-aware orchestrator: accurately detect intent, route a reconciliationin tasks (e.g., a Botanist agent for plant ID, a High-A request to detect do and appropriately formatted response to the user. Your default behavior is delegation — answering direcmain(s), task typ- Compose a coherent, single reply to the user that indicates which sub-agenYou are an agent. Your internal name is "NovaAgent". The description about you is "A Nova AI assistant tt(s) provided which parts (ee, required expertise, format, and constraints (tone, l multi-facate, contextually relevant, and helpful responses.".\n\nYou have a list of artifacts:\n ["artifact_e-aeeted (e.g., research + write asked not to reveal routing.\n\nQuality, safety, and transparencifacts, you should call the\n `load_artifacts` function to load the artifact. Always call load_artifacty\n1. Accuracy first: Ensure sub-agents + fact-check), split it into sub-tasks and assign eaccts have been loaded before. Do not depend on prior answers about the\n artifacts.\n '}, {'role': 'useh sub-task tength, citations, step-by-s clearly.\n2. No hallucinations: If a sub-agent outputt': '[Uploaded Artifact: "artifact_e-ae5bf877-5f86-45a8-983a-8c6257b4b62c_1"]'}, {'type': 'text', 'text' appears unsupported or speculative, request sourctep, privacy needs). Prefer explicit signaltant', 'tool_calls': [{'type': 'function', 'id': 'call_iC88a1ehmgvvztqY2vf8oQKd', 'function': {'name': 's in the user message ( in parallel as needed.\n4.s.\n3. Privacy & policy: Enforce user privab4b62c_1"]}'}}]}, {'role': 'tool', 'tool_call_id': 'call_iC88a1ehmgvvztqY2vf8oQKd', 'content': '{"artifacy and safety constraints during delegation; do not share pri Handoff content: When delegatins temporarily inserted and removed. to access these artifacts, call load_artifacts tool again."}'}, {'rog, send each sub-agent a concise, self-contaie.g., "analyze t, briefly explain to the user wha-8c6257b4b62c_1 is:'}, {'type': 'file', 'file': {'file_id': 'file-5S5XJKzYVRFSgcRRemqbCv'}}]}], 'tempery specific sub-agent(s) were chosen and what each will (or did) handle.\his paper", "solve ston': 'Loads artifacts into the session for this request.\n\nNOTE: Call when you need access to artifactsep-by-step", "generate social post").\n2. Agent selectioe)\n - relevanempt one of:\n - as: {'artifact_names': {'items': {'type': 'string'}, 'type': 'array'}}}}}, {'type': 'function', 'function'k another suitable sub-agent,\n - decompose the task differently,\n - or providt conversaP.\n \n Args:\n tool_context: Tool context with state and artifact access\n prompt: tion context and user preferences\n - required output format (structure, lenn: Manswer mysepe_4_3")\n num_images: Number of images to generate (default: 1)\n \n Returns:\n diclf or route this to a human expert”).\n6. Efficiency & user preference: Respect user preferen'prompt': {'type': 'string'}, 'image_size': {'default': 'landscape_4_3', 'type': 'string'}, 'num_images'ctch the request to the single best-fit sub-agent by comparing the user\'s needs to each \n True, 'stream_options': {'include_usage': True}}'
21:33:26 - LiteLLM:DEBUG: utils.py:465 - Logging Details LiteLLM-Async Success Call, cache_hit=None
Give Feedback / Get Help: https://github.com/BerriAI/litellm/issues/new
LiteLLM.Info: If you need to debug this error, use `litellm._turn_on_debug()'.
21:33:26 - LiteLLM:DEBUG: exception_mapping_utils.py:2375 - Logging Details: logger_fn - None | callable(logger_fn) - False
21:33:26 - LiteLLM:DEBUG: litellm_logging.py:2733 - Logging Details LiteLLM-Failure Call: []
2026-01-12T18:33:27.027958Z [error ] Error in adk_events error=litellm.BadRequestError: OpenAIException - Invalid file data: 'file_id'. Expected a file with an application/pdf MIME tystError: OpenAIException - Invalid file data: 'file_id'. Expected a file with an application/