psf/requests · error · InvalidHeader
Header part ( ) from must be of type str or bytes, not
Error message
Header part ({header_part!r}) from {header} must be of type str or bytes, not {type(header_part)} What it means
Raised by _validate_header_part() when a header name or value is neither str nor bytes (e.g., int, float, None, list). This is a runtime type guard — the type system expects str | bytes, but untyped callers can pass other types. It fires during request preparation before the request is sent.
Solutions
- Convert all header values to strings: headers={k: str(v) for k, v in headers.items()}.
- Filter out None values before setting headers: {k: v for k, v in headers.items() if v is not None}.
- Use a helper to normalize header dicts before passing to requests.
Example fix
# before
requests.get(url, headers={'Content-Length': 123, 'X-Token': None})
# after
headers = {k: str(v) for k, v in {'Content-Length': 123, 'X-Token': None}.items() if v is not None}
requests.get(url, headers=headers) Defensive patterns
Strategy: type-guard
Validate before calling
clean_headers = {
str(k): str(v)
for k, v in headers.items()
if v is not None
}
resp = requests.get(url, headers=clean_headers) Type guard
def has_valid_header_types(headers: dict) -> bool:
return all(
isinstance(k, (str, bytes)) and isinstance(v, (str, bytes))
for k, v in headers.items()
) Prevention
- Convert all header values to str before passing: {k: str(v) for k, v in headers.items()}.
- Filter out None values from header dicts before making requests.
- Use type annotations on header construction to catch type issues early.
When it happens
Trigger: Passing headers={'Content-Length': 123} (int value); headers={None: 'value'} (None key); headers={'X-Count': 3.14} (float); any header dict where name or value is not str or bytes.
Common situations: Computed numeric values passed directly as header values without str() conversion; JSON-parsed data used as headers without type coercion; None values from optional config passed through without filtering.
Related errors
- Invalid leading whitespace, reserved character(s), or…
- chunk_size must be an int, it is instead a
- cannot encode objects that are not 2-tuples
- Cookie headers should be added with…
- No connection adapters were found for
AI-assisted analysis of psf/requests@8068356288 (2026-08-11).
Data as JSON: /api/errors/3463071ff348f5e6.
Report an issue: GitHub.
Appendix: source
Thrown at src/requests/utils.py:1109
:param header: tuple, in the format (name, value).
"""
name, value = header
_validate_header_part(header, name, 0)
_validate_header_part(header, value, 1)
def _validate_header_part(
header: tuple[str | bytes, str | bytes],
header_part: str | bytes,
header_validator_index: int,
) -> None:
if isinstance(header_part, str):
validator = _HEADER_VALIDATORS_STR[header_validator_index]
elif isinstance(header_part, bytes):
# runtime guard for non-str/bytes input
validator = _HEADER_VALIDATORS_BYTE[header_validator_index]
else:
raise InvalidHeader(
f"Header part ({header_part!r}) from {header} "
f"must be of type str or bytes, not {type(header_part)}"
)
if not validator.match(header_part): # type: ignore[arg-type]
header_kind = "name" if header_validator_index == 0 else "value"
raise InvalidHeader(
f"Invalid leading whitespace, reserved character(s), or return "
f"character(s) in header {header_kind}: {header_part!r}"
)
def urldefragauth(url: str) -> str:
"""
Given a url remove the fragment and the authentication part.
:rtype: str
"""View on GitHub (pinned to 8068356288)