Skip to content

Interactions client sends duplicate User-Agent header (breaks aiohttp 3.13.4+ servers) #2309

@clemlesne

Description

@clemlesne

Description

The Interactions API client sends two User-Agent HTTP headers on every request, which causes strict HTTP servers (aiohttp 3.13.4+) to reject the request with 400 Bad Request: Duplicate 'User-Agent' header found.

Root cause

append_library_version_headers() in _api_client.py adds a lowercase user-agent key to the headers dict:

headers['user-agent'] = f'{library_label} {language_label}'

The Stainless-generated base class (AsyncAPIClient.default_headers) adds a title-case User-Agent key via its user_agent property:

@property
def default_headers(self) -> dict[str, str | Omit]:
    return {
        "User-Agent": self.user_agent,
        ...
        **self._custom_headers,  # ← contains lowercase 'user-agent' from adapter
    }

Since Python dicts are case-sensitive, the merged dict has both User-Agent and user-agent as separate keys. When passed to httpx.Headers(), they become two distinct header entries on the wire:

user-agent: AsyncGeminiNextGenAPIClient/Python 1.71.0
user-agent: google-genai-sdk/1.71.0 gl-python/3.14.3

Reproduction

from google import genai
from google.genai import types
import httpx

client = genai.Client(
    api_key="test",
    http_options=types.HttpOptions(api_version="v1beta", base_url="http://localhost:8080"),
)

ic = client.aio.interactions._client
h = httpx.Headers(ic.default_headers)
print(h.get_list("user-agent"))
# ['AsyncGeminiNextGenAPIClient/Python 1.71.0', 'google-genai-sdk/1.71.0 gl-python/3.14.3']

Impact

Affected versions

Tested on 1.71.0 and 1.72.0. Likely present since Interactions API was introduced.

Suggested fix

Unify the User-Agent to a single key in append_library_version_headers():

# Use title-case to match the Stainless base class key
headers['User-Agent'] = f'{library_label} {language_label}'
# Or remove the base class User-Agent and let the adapter be the sole source

Environment

  • google-genai: 1.71.0 / 1.72.0
  • Python: 3.14.3
  • aiohttp (server): 3.13.4+ (rejects), 3.13.3 (accepts)

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions