encode/httpx · error · TypeError
Invalid type for url. Expected str or httpx.URL, got {type(
Error message
Invalid type for url. Expected str or httpx.URL, got {type(url)}: {url!r} What it means
Raised by URL.__init__ when the first positional 'url' argument is neither a str nor an httpx.URL instance. The constructor only accepts those two types; anything else (int, dict, list, yarl.URL, urllib.parse.ParseResult, etc.) is rejected as TypeError before parsing.
Source
Thrown at httpx/_urls.py:121
raise TypeError(message)
if isinstance(value, bytes):
kwargs[key] = value.decode("ascii")
if "params" in kwargs:
# Replace any "params" keyword with the raw "query" instead.
#
# Ensure that empty params use `kwargs["query"] = None` rather
# than `kwargs["query"] = ""`, so that generated URLs do not
# include an empty trailing "?".
params = kwargs.pop("params")
kwargs["query"] = None if not params else str(QueryParams(params))
if isinstance(url, str):
self._uri_reference = urlparse(url, **kwargs)
elif isinstance(url, URL):
self._uri_reference = url._uri_reference.copy_with(**kwargs)
else:
raise TypeError(
"Invalid type for url. Expected str or httpx.URL,"
f" got {type(url)}: {url!r}"
)
@property
def scheme(self) -> str:
"""
The URL scheme, such as "http", "https".
Always normalised to lowercase.
"""
return self._uri_reference.scheme
@property
def raw_scheme(self) -> bytes:
"""
The raw bytes representation of the URL scheme, such as b"http", b"https".
Always normalised to lowercase.
"""View on GitHub (pinned to b5addb64f0)
Solutions
- Coerce to str first: httpx.URL(str(value)).
- If you have a urllib.parse result, pass .geturl() or reconstruct as a string.
- For cross-library code, convert foreign URL types (yarl.URL) via str() before httpx.URL.
- Add an isinstance(url, (str, httpx.URL)) guard at the boundary.
Example fix
// before
from urllib.parse import urlparse
parsed = urlparse("https://example.com")
url = httpx.URL(parsed) # TypeError: invalid type
// after
url = httpx.URL(parsed.geturl()) Defensive patterns
Strategy: type-guard
Validate before calling
import httpx
def to_url(url) -> httpx.URL:
if isinstance(url, httpx.URL):
return url
if isinstance(url, str):
return httpx.URL(url)
# urllib.parse.ParseResult, yarl.URL, etc.
return httpx.URL(str(url))
url = to_url(foreign_url_object) Type guard
def is_url_like(value) -> bool:
return isinstance(value, (str, httpx.URL)) Try / catch
try:
url = httpx.URL(value)
except TypeError as e:
if "Invalid type for url" in str(e):
url = httpx.URL(str(value))
else:
raise Prevention
- Always coerce foreign URL types (yarl, urllib.parse) via str() at the boundary.
- Add an isinstance(url, (str, httpx.URL)) guard in shared HTTP helpers.
- Treat None/int/dict inputs as programmer errors and fail fast.
When it happens
Trigger: httpx.URL(123), httpx.URL(None), httpx.URL(some_dict), httpx.URL(urllib.parse.urlparse('...')) (a ParseResult, not a str), or passing a yarl.URL by mistake.
Common situations: Inter-library confusion (yarl vs httpx.URL); passing the result of urlparse() directly; treating an int/None as a URL; building URLs from untyped config values.
Related errors
- {key!r} is an invalid keyword argument for URL()
- Argument {key!r} must be {expected} but got {seen}
- URL too long
- Invalid non-printable ASCII character in URL, {char!r} at po
- URL component '{key}' too long
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/6f4387e03c06f0e7.json.
Report an issue: GitHub.