D4Vinci/Scrapling · error · ValueError
At least one proxy must be provided
Error message
At least one proxy must be provided
What it means
Raised by `ProxyRotator.__init__` in scrapling/engines/toolbelt/proxy_rotation.py when the `proxies` list is empty. The rotator needs at least one proxy to cycle through, so an empty (or falsy) collection is rejected immediately rather than failing later during a request.
Source
Thrown at scrapling/engines/toolbelt/proxy_rotation.py:65
"""
__slots__ = ("_proxies", "_proxy_to_index", "_strategy", "_current_index", "_lock")
def __init__(
self,
proxies: List[ProxyType],
strategy: RotationStrategy = cyclic_rotation,
):
"""
Initialize the proxy rotator.
:param proxies: List of proxy URLs or Playwright-style proxy dicts.
- String format: "http://proxy1:8080" or "http://user:pass@proxy:8080"
- Dict format: {"server": "http://proxy:8080", "username": "user", "password": "pass"}
:param strategy: Rotation strategy function. Takes (proxies, current_index) and returns (proxy, next_index). Defaults to cyclic_rotation.
"""
if not proxies:
raise ValueError("At least one proxy must be provided")
if not callable(strategy):
raise TypeError(f"strategy must be callable, got {type(strategy).__name__}")
self._strategy = strategy
self._lock = Lock()
# Validate and store proxies
self._proxies: List[ProxyType] = []
self._proxy_to_index: Dict[str, int] = {} # O(1) lookup by unique key (server + username)
for i, proxy in enumerate(proxies):
if isinstance(proxy, (str, dict)):
if isinstance(proxy, dict) and "server" not in proxy:
raise ValueError("Proxy dict must have a 'server' key")
self._proxy_to_index[_get_proxy_key(proxy)] = i
self._proxies.append(proxy)
else:View on GitHub (pinned to 5d213a2d47)
Solutions
- Supply at least one proxy string or dict: ProxyRotator(proxies=['http://p1:8080']).
- Check the pool is non-empty after loading: if not pool: use direct connection instead of constructing the rotator.
- Log the pool size where proxies are loaded so an empty source is visible before the rotator is built.
Example fix
# before
rotator = ProxyRotator(proxies=load_proxies()) # may be []
# after
pool = load_proxies()
if not pool:
raise SystemExit('No proxies configured; aborting')
rotator = ProxyRotator(proxies=pool) Defensive patterns
Strategy: validation
Validate before calling
pool = load_proxies()
if not pool:
raise RuntimeError("proxy pool is empty; check proxy source before creating rotator")
rotator = ProxyRotator(proxies=pool) Try / catch
try:
rotator = ProxyRotator(proxies=pool)
except ValueError as e:
if "At least one proxy" in str(e):
rotator = None # fall back to direct connection path
else:
raise Prevention
- Assert a non-empty pool right where proxies are loaded.
- Log pool size at startup so empty sources are obvious.
- Decide the no-proxy behavior (abort vs direct) before constructing the rotator.
When it happens
Trigger: Constructing ProxyRotator(proxies=[]) or ProxyRotator(proxies=[]) with a list produced by filtering, e.g. [p for p in pool if p] where everything was filtered out, or passing an empty default when no proxies were configured.
Common situations: Loading proxies from a file/env var that is empty on some machines; a proxy-fetching API returning zero results; CI environments without proxy credentials so the configured pool is empty.
Related errors
- Proxy dict must have a 'server' key
- Invalid proxy type: {type(proxy)}. Expected str or dict.
- Cannot use 'proxy_rotator' together with 'proxy'. Use either
- Cannot use 'proxy_rotator' together with 'proxy' or 'proxies
- Invalid proxy string!
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/74e33edc6b84c4a5.
Report an issue: GitHub.