🔴 Required Information
Describe the Bug:
google.adk.models.lite_llm.LiteLlm uploads inline PDF attachments to Azure
using raw bytes without a filename or content type.
This occurs with a direct Azure model identifier:
ADK correctly recognizes Azure and enters its OpenAI/Azure file-upload path.
However, it calls litellm.acreate_file() like this:
await litellm.acreate_file(
file=part.inline_data.data,
purpose="assistants",
custom_llm_provider="azure",
)
Because file is only a bytes object, the upload carries neither a filename
such as document.pdf nor the application/pdf content type. Azure stores or
interprets the uploaded file as having no recognized file type and rejects it
when the file is used as model input.
Steps to Reproduce:
-
Install the dependencies:
pip install google-adk litellm google-genai
-
Configure credentials and endpoint information for an Azure OpenAI
deployment that supports PDF input.
-
Construct an ADK model using a direct Azure identifier:
from google.adk.models.lite_llm import LiteLlm
model = LiteLlm(model="azure/<deployment>")
-
Send a user message containing an inline PDF:
from google.genai import types
message = types.Content(
role="user",
parts=[
types.Part(text="Describe this PDF"),
types.Part(
inline_data=types.Blob(
mime_type="application/pdf",
data=pdf_bytes,
)
),
],
)
-
Observe that Azure rejects the request before inference:
Invalid input: Expected context stuffing file type to be a supported
format: ... .pdf ... but got none.
A network-free reproduction of the upload arguments is included below.
Expected Behavior:
When uploading an inline_data part whose MIME type is application/pdf, ADK
should preserve sufficient file metadata for Azure to recognize the uploaded
file as a PDF.
The file upload should include both:
- a filename with a supported extension, such as
.pdf; and
- the
application/pdf content type.
The uploaded file should then be usable as model input.
Observed Behavior:
ADK passes only the raw PDF bytes to litellm.acreate_file().
Azure later rejects the uploaded file with:
Invalid input: Expected context stuffing file type to be a supported format:
... .pdf ... but got none.
The error response identifies input as the invalid parameter:
{
"error": {
"message": "Invalid input: Expected context stuffing file type to be a supported format: ... .pdf ... but got none.",
"type": "invalid_request_error",
"param": "input",
"code": null
}
}
The request is rejected before any model inference occurs.
Environment Details:
- ADK Library Version:
google-adk 2.6.0
- Desktop OS: macOS
- Python Version:
3.11
- LiteLLM Version:
1.94.1
- google-genai Version:
2.16.0
Model Information:
- Are you using LiteLLM: Yes
- Which model is being used: an Azure OpenAI deployment through the direct
azure/<deployment> route
🟡 Optional Information
Regression:
Not known to have worked previously.
This appears to be an incomplete resolution of #4174 rather than a new
regression. The behavior remains present in ADK 2.6.0 and current main.
Logs:
BadRequestError: litellm.BadRequestError: AzureException BadRequestError - {
"error": {
"message": "Invalid input: Expected context stuffing file type to be a supported format: ... .pdf ... but got none.",
"type": "invalid_request_error",
"param": "input",
"code": null
}
}
Additional Context:
Issue #4174 reported that PDF attachments sent through LiteLlm to OpenAI/Azure
were seen with a missing file type.
It was closed by commit
065234e27973d4af0084cbac1db3d21561ba6e66, which added the MIME type to the
file reference created after upload:
{
"type": "file",
"file": {
"file_id": file_response.id,
"format": mime_type,
},
}
However, that change did not add metadata to the file upload itself. Current
code still performs the upload with:
file_response = await litellm.acreate_file(
file=part.inline_data.data,
purpose="assistants",
custom_llm_provider=provider,
)
Adding "format": "application/pdf" to the later file reference cannot restore
the filename or MIME metadata that was absent when the file was uploaded.
A previous proposed fix in #4603 passed a (filename, bytes, mime_type) tuple
to acreate_file(), but that PR was closed without merging.
Minimal Reproduction Code:
The following reproduction makes no provider request. It intercepts
acreate_file() and shows the value ADK supplies for file:
import asyncio
from google.adk.models import lite_llm as adk_lite_llm
from google.genai import types
async def main():
adk_lite_llm._ensure_litellm_imported()
captured = {}
original_acreate_file = adk_lite_llm.litellm.acreate_file
async def capture_acreate_file(**kwargs):
captured.update(kwargs)
class FileResponse:
id = "assistant-demo"
return FileResponse()
adk_lite_llm.litellm.acreate_file = capture_acreate_file
try:
content = await adk_lite_llm._get_content(
[
types.Part(text="Describe this PDF"),
types.Part(
inline_data=types.Blob(
mime_type="application/pdf",
data=b"%PDF-1.4\n",
)
),
],
provider="azure",
model="azure/example-deployment",
)
finally:
adk_lite_llm.litellm.acreate_file = original_acreate_file
print("file type:", type(captured["file"]).__name__)
print("file value:", repr(captured["file"]))
print("purpose:", captured["purpose"])
print("provider:", captured["custom_llm_provider"])
print("content:", content)
asyncio.run(main())
Observed output:
file type: bytes
file value: b'%PDF-1.4\n'
purpose: assistants
provider: azure
content: [
{'type': 'text', 'text': 'Describe this PDF'},
{
'type': 'file',
'file': {
'file_id': 'assistant-demo',
'format': 'application/pdf'
}
}
]
This demonstrates that the subsequent content block carries the MIME type, but
the upload itself receives only anonymous raw bytes.
How often has this issue occurred?:
Relationship to #6538
This issue is related to #6538 because both affect PDF input through LiteLlm, but they are not duplicates:
Fixing #6538 may cause that proxy route to reach the upload path described here, where it could still fail until this separate metadata defect is resolved. Fixing this issue alone would not correct the nested-provider detection in #6538.
🔴 Required Information
Describe the Bug:
google.adk.models.lite_llm.LiteLlmuploads inline PDF attachments to Azureusing raw bytes without a filename or content type.
This occurs with a direct Azure model identifier:
ADK correctly recognizes Azure and enters its OpenAI/Azure file-upload path.
However, it calls
litellm.acreate_file()like this:Because
fileis only abytesobject, the upload carries neither a filenamesuch as
document.pdfnor theapplication/pdfcontent type. Azure stores orinterprets the uploaded file as having no recognized file type and rejects it
when the file is used as model input.
Steps to Reproduce:
Install the dependencies:
Configure credentials and endpoint information for an Azure OpenAI
deployment that supports PDF input.
Construct an ADK model using a direct Azure identifier:
Send a user message containing an inline PDF:
Observe that Azure rejects the request before inference:
A network-free reproduction of the upload arguments is included below.
Expected Behavior:
When uploading an
inline_datapart whose MIME type isapplication/pdf, ADKshould preserve sufficient file metadata for Azure to recognize the uploaded
file as a PDF.
The file upload should include both:
.pdf; andapplication/pdfcontent type.The uploaded file should then be usable as model input.
Observed Behavior:
ADK passes only the raw PDF bytes to
litellm.acreate_file().Azure later rejects the uploaded file with:
The error response identifies
inputas the invalid parameter:{ "error": { "message": "Invalid input: Expected context stuffing file type to be a supported format: ... .pdf ... but got none.", "type": "invalid_request_error", "param": "input", "code": null } }The request is rejected before any model inference occurs.
Environment Details:
google-adk 2.6.03.111.94.12.16.0Model Information:
azure/<deployment>route🟡 Optional Information
Regression:
Not known to have worked previously.
This appears to be an incomplete resolution of #4174 rather than a new
regression. The behavior remains present in ADK 2.6.0 and current
main.Logs:
Additional Context:
Issue #4174 reported that PDF attachments sent through LiteLlm to OpenAI/Azure
were seen with a missing file type.
It was closed by commit
065234e27973d4af0084cbac1db3d21561ba6e66, which added the MIME type to thefile reference created after upload:
{ "type": "file", "file": { "file_id": file_response.id, "format": mime_type, }, }However, that change did not add metadata to the file upload itself. Current
code still performs the upload with:
Adding
"format": "application/pdf"to the later file reference cannot restorethe filename or MIME metadata that was absent when the file was uploaded.
A previous proposed fix in #4603 passed a
(filename, bytes, mime_type)tupleto
acreate_file(), but that PR was closed without merging.Minimal Reproduction Code:
The following reproduction makes no provider request. It intercepts
acreate_file()and shows the value ADK supplies forfile:Observed output:
This demonstrates that the subsequent content block carries the MIME type, but
the upload itself receives only anonymous raw bytes.
How often has this issue occurred?:
Relationship to #6538
This issue is related to #6538 because both affect PDF input through
LiteLlm, but they are not duplicates:azure/<deployment>route. ADK correctly identifies Azure and enters the Files API upload branch, but uploads anonymous raw bytes without a filename or MIME metadata.litellm_proxy/azure/<deployment>. ADK identifies only the outerlitellm_proxyprovider, skips Azure/OpenAI file upload entirely, and emits inlinefile_datathat becomes an invalid Azureinput_file.Fixing #6538 may cause that proxy route to reach the upload path described here, where it could still fail until this separate metadata defect is resolved. Fixing this issue alone would not correct the nested-provider detection in #6538.