{"id":"6f4387e03c06f0e7","repo":"encode/httpx","slug":"invalid-type-for-url-expected-str-or-httpx-url","errorCode":null,"errorMessage":"Invalid type for url.  Expected str or httpx.URL, got {type(url)}: {url!r}","messagePattern":"Invalid type for url\\.  Expected str or httpx\\.URL, got (.+?): (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"httpx/_urls.py","lineNumber":121,"sourceCode":"                    raise TypeError(message)\n                if isinstance(value, bytes):\n                    kwargs[key] = value.decode(\"ascii\")\n\n            if \"params\" in kwargs:\n                # Replace any \"params\" keyword with the raw \"query\" instead.\n                #\n                # Ensure that empty params use `kwargs[\"query\"] = None` rather\n                # than `kwargs[\"query\"] = \"\"`, so that generated URLs do not\n                # include an empty trailing \"?\".\n                params = kwargs.pop(\"params\")\n                kwargs[\"query\"] = None if not params else str(QueryParams(params))\n\n        if isinstance(url, str):\n            self._uri_reference = urlparse(url, **kwargs)\n        elif isinstance(url, URL):\n            self._uri_reference = url._uri_reference.copy_with(**kwargs)\n        else:\n            raise TypeError(\n                \"Invalid type for url.  Expected str or httpx.URL,\"\n                f\" got {type(url)}: {url!r}\"\n            )\n\n    @property\n    def scheme(self) -> str:\n        \"\"\"\n        The URL scheme, such as \"http\", \"https\".\n        Always normalised to lowercase.\n        \"\"\"\n        return self._uri_reference.scheme\n\n    @property\n    def raw_scheme(self) -> bytes:\n        \"\"\"\n        The raw bytes representation of the URL scheme, such as b\"http\", b\"https\".\n        Always normalised to lowercase.\n        \"\"\"","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_urls.py#L103-L139","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfrom urllib.parse import urlparse\nparsed = urlparse(\"https://example.com\")\nurl = httpx.URL(parsed)  # TypeError: invalid type\n\n// after\nurl = httpx.URL(parsed.geturl())","handlingStrategy":"type-guard","validationCode":"import httpx\n\ndef to_url(url) -> httpx.URL:\n    if isinstance(url, httpx.URL):\n        return url\n    if isinstance(url, str):\n        return httpx.URL(url)\n    # urllib.parse.ParseResult, yarl.URL, etc.\n    return httpx.URL(str(url))\n\nurl = to_url(foreign_url_object)","typeGuard":"def is_url_like(value) -> bool:\n    return isinstance(value, (str, httpx.URL))","tryCatchPattern":"try:\n    url = httpx.URL(value)\nexcept TypeError as e:\n    if \"Invalid type for url\" in str(e):\n        url = httpx.URL(str(value))\n    else:\n        raise","preventionTips":["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."],"tags":["url","type-mismatch","validation","typeerror","api-misuse"],"analyzedSha":"b5addb64f0161ff6bfe94c124ef76f6a1fba5254","analyzedAt":"2026-08-04T19:32:56.768Z","schemaVersion":2}