D4Vinci/Scrapling · error · TypeError
Invalid proxy dictionary: {e}
Error message
Invalid proxy dictionary: {e} What it means
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.
Source
Thrown at scrapling/engines/toolbelt/navigation.py:128
result = {
"server": f"{proxy.scheme}://{proxy.hostname}",
"username": proxy.username or "",
"password": proxy.password or "",
}
if proxy.port:
result["server"] += f":{proxy.port}"
return result
except ValueError:
# Urllib will say that one of the parameters above can't be casted to the correct type like `int` for port etc...
raise ValueError("The proxy argument's string is in invalid format!")
elif isinstance(proxy_string, dict):
try:
validated = convert(proxy_string, ProxyDict)
result_dict = structs.asdict(validated)
return result_dict
except ValidationError as e:
raise TypeError(f"Invalid proxy dictionary: {e}")
raise TypeError(f"Invalid proxy string: {proxy_string}")
View on GitHub (pinned to 5d213a2d47)
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.
Example fix
# before
proxy = {"http": "http://proxy:8080"}
# after
proxy = {"server": "http://proxy:8080", "username": "user", "password": "pass"} Defensive patterns
Strategy: validation
Validate before calling
def is_valid_proxy_dict(d: dict) -> bool:
return (
isinstance(d, dict)
and isinstance(d.get("server"), str)
and all(isinstance(d.get(k, ""), str) for k in ("username", "password"))
)
assert is_valid_proxy_dict(proxy_dict), proxy_dict Type guard
from typing import Any
def is_proxy_dict(value: Any) -> bool:
return isinstance(value, dict) and isinstance(value.get("server"), str) Try / catch
try:
fetcher.fetch(url, proxy=proxy_dict)
except TypeError as e:
if "Invalid proxy dictionary" in str(e):
raise ConfigError("proxy dict needs server/username/password as strings") from e
raise Prevention
- 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.
When it happens
Trigger: 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': ...}.
Common situations: 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.
Related errors
- Invalid proxy string!
- 'quality' is only valid when 'image_type' is 'jpeg'.
- Browser not initialized for proxy rotation mode
- Cannot use 'proxy_rotator' together with 'proxy'. Use either
- Cannot use 'proxy_rotator' together with 'proxy' or 'proxies
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/d546a280ab59f3fd.
Report an issue: GitHub.