Skip to content

[Bug] LiteLlm sends invalid PDF content for Azure-backed models through litellm_proxy #6538

Description

@ross-p

🔴 Required Information

Describe the Bug:

google.adk.models.lite_llm.LiteLlm does not correctly handle PDF
attachments when an Azure-backed model is accessed through a LiteLLM Proxy
using a nested model identifier such as:

litellm_proxy/azure/<deployment>

ADK derives provider-specific file behavior from the first segment of the
model identifier. _get_provider_from_model() therefore classifies the
provider as litellm_proxy, rather than recognizing that the proxied model
ultimately uses Azure.

This bypasses ADK's OpenAI/Azure file-upload path. Instead of uploading the PDF
and sending a file_id, ADK produces a generic inline file block containing
only file_data. When the proxy translates that block for the Azure Responses
API, Azure rejects the resulting input_file content item as incomplete.

Steps to Reproduce:

  1. Install the relevant packages:

    pip install google-adk litellm google-genai
  2. Configure a LiteLLM Proxy model backed by an Azure OpenAI Responses API
    deployment.

  3. Construct an ADK LiteLlm using a nested proxy model identifier:

    LiteLlm(model="litellm_proxy/azure/<deployment>")
  4. Send a user message containing an application/pdf inline_data part.

  5. Observe that Azure rejects the request before inference with an error such
    as:

    BadRequestError: AzureException BadRequestError
    Missing required parameter: 'input[0].content[3]'
    

    The indexed content item is the PDF attachment.

A network-free reproduction of the conversion decision is:

import asyncio

from google.adk.models import lite_llm
from google.genai import types

model = "litellm_proxy/azure/example-deployment"

parts = [
    types.Part(text="Context"),
    types.Part(text="Describe this PDF"),
    types.Part(text="Attached file: example.pdf"),
    types.Part(
        inline_data=types.Blob(
            mime_type="application/pdf",
            data=b"%PDF-1.4\n% minimal reproduction\n",
        )
    ),
]

provider = lite_llm._get_provider_from_model(model)
content = asyncio.run(
    lite_llm._get_content(parts, provider=provider, model=model)
)

print("provider:", provider)
print("file keys:", content[-1]["file"].keys())

Observed output:

provider: litellm_proxy
file keys: dict_keys(['file_data'])

The resulting file block is equivalent to:

{
  "type": "file",
  "file": {
    "file_data": "data:application/pdf;base64,..."
  }
}

It has no Azure/OpenAI file_id and no filename.

Expected Behavior:

PDF attachments should remain usable when an Azure-backed model is accessed
through LiteLLM Proxy.

ADK should either:

  • preserve enough underlying-provider information to select the appropriate
    Azure/OpenAI file representation, or
  • provide another supported way to communicate the proxied provider's file
    requirements.

At minimum, it should not produce a request that is reported as supported but
is deterministically rejected by the downstream provider.

Observed Behavior:

ADK treats litellm_proxy as the final provider and takes its generic inline
file-data path. The proxy subsequently forwards an incomplete input_file
representation to Azure, which rejects the request with HTTP 400 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 Responses API deployment accessed
    through litellm_proxy/azure/<deployment>

🟡 Optional Information

Regression:

Not known to have worked in an earlier ADK release. Current provider detection
takes only the first segment of a LiteLLM model identifier, so this appears to
be a missing proxy-routing case rather than a regression.

Logs:

BadRequestError: litellm.BadRequestError: Error code: 400
AzureException BadRequestError:
Missing required parameter: 'input[0].content[3]'.
type: invalid_request_error
code: missing_required_parameter

No model call is completed and no tokens are consumed.

Additional Context:

The direct-provider cases have related prior reports:

Those reports cover adjacent file-conversion defects, but they do not appear to
cover provider-specific file handling being lost because the model identifier
starts with litellm_proxy/.

The relevant provider detection currently behaves approximately as follows:

provider, _ = model.split("/", 1)

For litellm_proxy/azure/<deployment>, this necessarily returns
litellm_proxy. The PDF converter's upload path, however, is selected only
when the provider is exactly openai or azure.

How often has this issue occurred?:

  • Always (100%) for this route and PDF input

Relationship to #6539

This issue is related to #6539 because both affect PDF input through LiteLlm, but they are not duplicates:

Fixing #6539 alone would not make the proxy route enter Azure-specific file handling. Conversely, fixing this issue so the nested route selects the Azure upload path may then expose #6539 unless the upload-metadata defect is also resolved.

Metadata

Metadata

Assignees

Labels

models[Component] This issue is related to model supportrequest clarification[Status] The maintainer need clarification or more information from the author

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions