D4Vinci/Scrapling · error · TypeError

Invalid proxy string: {proxy_string}

Error message

Invalid proxy string: {proxy_string}

What it means

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.

Source

Thrown at scrapling/engines/toolbelt/navigation.py:130

                "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

  1. Pass the proxy as a URL string 'http://host:port' or a dict {'server': ..., 'username': ..., 'password': ...}.
  2. If the proxy is optional, omit the argument entirely or branch your code so it is only passed when set.
  3. Flatten tuple/list configs into one of the two accepted shapes before calling the fetcher.

Example fix

# before
proxy = ("http", "proxy1", 8080)
Fetcher.get(url, proxy=proxy)

# after
proxy = "http://proxy1:8080"
Fetcher.get(url, proxy=proxy)
Defensive patterns

Strategy: type-guard

Validate before calling

def normalize_proxy(value):
    if isinstance(value, str) or (isinstance(value, dict) and "server" in value):
        return value
    raise TypeError(f"Unsupported proxy type {type(value).__name__}; use str or dict")

fetcher.fetch(url, proxy=normalize_proxy(proxy))

Type guard

def is_supported_proxy(value: object) -> bool:
    return isinstance(value, (str, dict)) and not isinstance(value, tuple)

Try / catch

try:
    fetcher.fetch(url, proxy=proxy)
except TypeError as e:
    if "Invalid proxy string" in str(e):
        raise ConfigError('proxy must be a URL string or {server,username,password} dict') from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14). Data as JSON: /api/errors/0fe3903001d30fb1. Report an issue: GitHub.