{"record":{"id":"0fe3903001d30fb1","repo":"D4Vinci/Scrapling","slug":"invalid-proxy-string-proxy-string","errorCode":null,"errorMessage":"Invalid proxy string: {proxy_string}","messagePattern":"Invalid proxy string: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"scrapling/engines/toolbelt/navigation.py","lineNumber":130,"sourceCode":"                \"username\": proxy.username or \"\",\n                \"password\": proxy.password or \"\",\n            }\n            if proxy.port:\n                result[\"server\"] += f\":{proxy.port}\"\n            return result\n        except ValueError:\n            # Urllib will say that one of the parameters above can't be casted to the correct type like `int` for port etc...\n            raise ValueError(\"The proxy argument's string is in invalid format!\")\n\n    elif isinstance(proxy_string, dict):\n        try:\n            validated = convert(proxy_string, ProxyDict)\n            result_dict = structs.asdict(validated)\n            return result_dict\n        except ValidationError as e:\n            raise TypeError(f\"Invalid proxy dictionary: {e}\")\n\n    raise TypeError(f\"Invalid proxy string: {proxy_string}\")\n","sourceCodeStart":112,"sourceCodeEnd":131,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/engines/toolbelt/navigation.py#L112-L131","documentation":"The catch-all TypeError at the end of `construct_proxy_dict`: the proxy argument was neither a `str` nor a `dict`, so scrapling has no idea how to interpret it. The function only accepts those two shapes for a proxy; anything else (None, list, tuple, object) is rejected. Note the type hint says `str | Dict[str, str] | Tuple` but the implementation does not actually handle tuples.","triggerScenarios":"Calling a fetcher with proxy=None explicitly, proxy=('http', 'proxy', 8080) as a tuple, proxy=['http://proxy:8080'] as a list, or passing a Playwright Proxy object.","commonSituations":"Reading proxy config from YAML/JSON that deserializes to a list; passing a tuple because the type hint mentions Tuple; passing None from an optional config variable without a default.","solutions":["Pass the proxy as a URL string 'http://host:port' or a dict {'server': ..., 'username': ..., 'password': ...}.","If the proxy is optional, omit the argument entirely or branch your code so it is only passed when set.","Flatten tuple/list configs into one of the two accepted shapes before calling the fetcher."],"exampleFix":"# before\nproxy = (\"http\", \"proxy1\", 8080)\nFetcher.get(url, proxy=proxy)\n\n# after\nproxy = \"http://proxy1:8080\"\nFetcher.get(url, proxy=proxy)","handlingStrategy":"type-guard","validationCode":"def normalize_proxy(value):\n    if isinstance(value, str) or (isinstance(value, dict) and \"server\" in value):\n        return value\n    raise TypeError(f\"Unsupported proxy type {type(value).__name__}; use str or dict\")\n\nfetcher.fetch(url, proxy=normalize_proxy(proxy))","typeGuard":"def is_supported_proxy(value: object) -> bool:\n    return isinstance(value, (str, dict)) and not isinstance(value, tuple)","tryCatchPattern":"try:\n    fetcher.fetch(url, proxy=proxy)\nexcept TypeError as e:\n    if \"Invalid proxy string\" in str(e):\n        raise ConfigError('proxy must be a URL string or {server,username,password} dict') from e\n    raise","preventionTips":["Never pass tuples/lists/None as proxy; omit the argument for direct connection.","Guard optional proxies: pass proxy only if it is not None.","Read the exception text — it echoes the offending value."],"tags":["proxy","type-error","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}