{"record":{"id":"d546a280ab59f3fd","repo":"D4Vinci/Scrapling","slug":"invalid-proxy-dictionary-e","errorCode":null,"errorMessage":"Invalid proxy dictionary: {e}","messagePattern":"Invalid proxy dictionary: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"scrapling/engines/toolbelt/navigation.py","lineNumber":128,"sourceCode":"            result = {\n                \"server\": f\"{proxy.scheme}://{proxy.hostname}\",\n                \"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":110,"sourceCodeEnd":131,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/engines/toolbelt/navigation.py#L110-L131","documentation":"Raised when the `proxy` argument is a dict but it fails schema validation: scrapling converts it to a `ProxyDict` structure (via msgspec-style `convert`) and re-raises the `ValidationError` as a TypeError. The dict is expected to have exactly the keys 'server', 'username', and 'password'. Any missing required key, wrong value type, or unexpected/unknown key makes validation fail.","triggerScenarios":"Passing proxy={'server': 'http://p:8080'} (missing username/password), proxy={'server': 8080} (server not a str), proxy={'proxy': '...'} (wrong key name), or including extra keys not in ProxyDict such as {'server': ..., 'bypass': ...}.","commonSituations":"Copying a requests-style dict ({'http': url, 'https': url}) instead of Playwright style; renaming keys; partial dicts from environment variables or config files where optional keys were dropped.","solutions":["Provide all three keys with string values: {'server': 'http://host:port', 'username': 'user', 'password': 'pass'}.","If auth is not needed, still include 'username': '' and 'password': '' — check the ProxyDict definition for which fields are optional.","Remove requests-style keys like 'http'/'https' and any extra keys not in the schema.","Include the original ValidationError text (it is embedded in the message) to see exactly which field failed."],"exampleFix":"# before\nproxy = {\"http\": \"http://proxy:8080\"}\n\n# after\nproxy = {\"server\": \"http://proxy:8080\", \"username\": \"user\", \"password\": \"pass\"}","handlingStrategy":"validation","validationCode":"def is_valid_proxy_dict(d: dict) -> bool:\n    return (\n        isinstance(d, dict)\n        and isinstance(d.get(\"server\"), str)\n        and all(isinstance(d.get(k, \"\"), str) for k in (\"username\", \"password\"))\n    )\n\nassert is_valid_proxy_dict(proxy_dict), proxy_dict","typeGuard":"from typing import Any\n\ndef is_proxy_dict(value: Any) -> bool:\n    return isinstance(value, dict) and isinstance(value.get(\"server\"), str)","tryCatchPattern":"try:\n    fetcher.fetch(url, proxy=proxy_dict)\nexcept TypeError as e:\n    if \"Invalid proxy dictionary\" in str(e):\n        raise ConfigError(\"proxy dict needs server/username/password as strings\") from e\n    raise","preventionTips":["Use exactly the keys 'server', 'username', 'password'.","Do not pass requests-style {'http': ..., 'https': ...} dicts.","Build proxy dicts in one factory function shared by all fetchers."],"tags":["proxy","validation","playwright","schema"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}