encode/httpx · error · TypeError

{key!r} is an invalid keyword argument for URL()

Error message

{key!r} is an invalid keyword argument for URL()

What it means

Raised by URL.__init__ when a keyword argument name is not in the allowed set {scheme, username, password, userinfo, host, port, netloc, path, query, raw_path, fragment, params}. This is a strict constructor: any other kwarg is a programmer error and rejected as TypeError before any parsing.

Source

Thrown at httpx/_urls.py:98

                "scheme": str,
                "username": str,
                "password": str,
                "userinfo": bytes,
                "host": str,
                "port": int,
                "netloc": bytes,
                "path": str,
                "query": bytes,
                "raw_path": bytes,
                "fragment": str,
                "params": object,
            }

            # Perform type checking for all supported keyword arguments.
            for key, value in kwargs.items():
                if key not in allowed:
                    message = f"{key!r} is an invalid keyword argument for URL()"
                    raise TypeError(message)
                if value is not None and not isinstance(value, allowed[key]):
                    expected = allowed[key].__name__
                    seen = type(value).__name__
                    message = f"Argument {key!r} must be {expected} but got {seen}"
                    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):

View on GitHub (pinned to b5addb64f0)

Solutions

  1. Check the allowed keys list and remove unsupported kwargs before construction.
  2. Pass request-level options (timeout, headers) to client.request()/client.get(), not to URL().
  3. Filter kwargs through an allowlist when spreading a dynamic dict.
  4. Use an IDE/linter to catch unknown kwargs at authoring time.

Example fix

// before
url = httpx.URL("https://example.com", timeout=5.0)  # TypeError: invalid keyword

// after
url = httpx.URL("https://example.com")
client.get(url, timeout=5.0)
Defensive patterns

Strategy: type-guard

Validate before calling

ALLOWED_URL_KWARGS = {
    "scheme", "username", "password", "userinfo", "host", "port",
    "netloc", "path", "query", "raw_path", "fragment", "params",
}

def filtered_url_kwargs(kwargs: dict) -> dict:
    bad = set(kwargs) - ALLOWED_URL_KWARGS
    if bad:
        raise TypeError(f"Unsupported URL kwargs: {sorted(bad)}")
    return kwargs

url = httpx.URL(base, **filtered_url_kwargs(user_kwargs))

Type guard

def are_valid_url_kwargs(kwargs: dict) -> bool:
    allowed = {
        "scheme", "username", "password", "userinfo", "host", "port",
        "netloc", "path", "query", "raw_path", "fragment", "params",
    }
    return set(kwargs).issubset(allowed)

Try / catch

try:
    url = httpx.URL(base, **kwargs)
except TypeError as e:
    if "invalid keyword argument for URL()" in str(e):
        raise TypeError(f"Bad URL kwarg. Allowed: scheme/username/password/host/...") from e
    raise

Prevention

When it happens

Trigger: httpx.URL('https://x', timeout=10), httpx.URL(method='GET'), httpx.URL(headers=...), or any typo like httpx.URL('https://x', passwrod='x').

Common situations: Confusing URL constructor kwargs with Client kwargs (timeout, headers, auth); spelling mistakes; passing through an unvalidated dict as **kwargs.

Related errors


AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04). Data as JSON: /data/errors/cdc0614f164b3c00.json. Report an issue: GitHub.