openai/openai-python · error · ValueError
Could not find {header} header
Error message
Could not find {header} header What it means
get_required_header looks up a header in an httpx.Headers mapping using several casings (exact, lower, upper, intercaps). If none of the variants yields a truthy value it raises this ValueError — the expected header is entirely absent or empty. In the SDK it is used to extract response headers like x-request-id or the retry-after header during retry/error handling.
Source
Thrown at src/openai/_utils/_utils.py:404
def get_required_header(headers: HeadersLike, header: str) -> str:
lower_header = header.lower()
if is_mapping_t(headers):
# mypy doesn't understand the type narrowing here
for k, v in headers.items(): # type: ignore
if k.lower() == lower_header and isinstance(v, str):
return v
# to deal with the case where the header looks like X-Request-Id
intercaps_header = re.sub(r"([^\w])(\w)", lambda pat: pat.group(1) + pat.group(2).upper(), header.capitalize())
for normalized_header in [header, lower_header, header.upper(), intercaps_header]:
value = headers.get(normalized_header)
if value:
return value
raise ValueError(f"Could not find {header} header")
def get_async_library() -> str:
try:
return sniffio.current_async_library()
except Exception:
return "false"
def lru_cache(*, maxsize: int | None = 128) -> Callable[[CallableT], CallableT]:
"""A version of functools.lru_cache that retains the type signature
for the wrapped function arguments.
"""
wrapper = functools.lru_cache( # noqa: TID251
maxsize=maxsize,
)
return cast(Any, wrapper) # type: ignore[no-any-return]
View on GitHub (pinned to 9917c6e28e)
Solutions
- If mocking, include the real headers (x-request-id, retry-after where applicable) in mocked responses
- Point base_url at a backend that returns OpenAI-compatible response headers
- Update proxy/gateway config to forward the relevant headers instead of stripping them
- Catch ValueError around header-dependent logic if you support arbitrary backends
Example fix
# before
def handler(request):
return httpx.Response(200, json={...}) # no headers
# after
def handler(request):
return httpx.Response(200, json={...}, headers={"x-request-id": "req_1"}) Defensive patterns
Strategy: try-catch
Validate before calling
headers = response.headers
if not any(headers.get(v) for v in (name, name.lower(), name.upper())):
skip_header_logic() Type guard
def has_header(headers: object, name: str) -> bool:
return bool(isinstance(headers, dict) and headers.get(name)) or bool(getattr(headers, "get", lambda k: None)(name)) Try / catch
try:
rid = get_required_header(response.headers, "x-request-id")
except ValueError:
rid = None Prevention
- Include real headers when mocking responses
- Test mocks against captured real responses
- Configure proxies to forward headers
When it happens
Trigger: Responses from proxies, gateways, or test doubles (httpx.MockTransport, respx) that omit headers the SDK expects, e.g. a mocked error response missing retry-after or x-request-id; custom base_url servers not returning expected headers.
Common situations: Mocking SDK responses in tests without copying real headers; routing the SDK through corporate proxies or API gateways that strip headers; using OpenAI-compatible third-party backends that don't emit x-request-id.
Related errors
- The `default_headers` and `set_default_headers` arguments ar
- Pagination is only supported with mappings
- "Could not resolve authentication method. Expected either ap
- The `default_query` and `set_default_query` arguments are mu
- invalid datetime format
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/27bf3bd687f8612e.
Report an issue: GitHub.