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)
Description
The Interactions API client sends two
User-AgentHTTP headers on every request, which causes strict HTTP servers (aiohttp 3.13.4+) to reject the request with400 Bad Request: Duplicate 'User-Agent' header found.Root cause
append_library_version_headers()in_api_client.pyadds a lowercaseuser-agentkey to the headers dict:The Stainless-generated base class (
AsyncAPIClient.default_headers) adds a title-caseUser-Agentkey via itsuser_agentproperty:Since Python dicts are case-sensitive, the merged dict has both
User-Agentanduser-agentas separate keys. When passed tohttpx.Headers(), they become two distinct header entries on the wire:Reproduction
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():Environment