D4Vinci/Scrapling · error · ValueError
Cannot use 'proxy_rotator' together with 'proxy' or 'proxies
Error message
Cannot use 'proxy_rotator' together with 'proxy' or 'proxies'. Use either a static proxy or proxy rotation, not both.
What it means
Raised in _ConfigurationLogic.__init__ (the base of every static fetcher/session class) when the constructor receives both a proxy_rotator and a static proxy/proxies argument. Scrapling treats proxy rotation and static proxying as mutually exclusive strategies, so it fails fast at construction time instead of silently letting one override the other. This is a configuration contract error, not a network error.
Source
Thrown at scrapling/engines/static.py:92
self._stealth = kwargs.get("stealthy_headers", True)
self._default_proxies = kwargs.get("proxies") or {}
self._default_proxy = kwargs.get("proxy") or None
self._default_proxy_auth = kwargs.get("proxy_auth") or None
self._default_timeout = kwargs.get("timeout", 30)
self._default_headers = kwargs.get("headers") or {}
self._default_retries = kwargs.get("retries", 3)
self._default_retry_delay = kwargs.get("retry_delay", 1)
self._default_follow_redirects = kwargs.get("follow_redirects", "safe")
self._default_max_redirects = kwargs.get("max_redirects", 30)
self._default_verify = kwargs.get("verify", True)
self._default_cert = kwargs.get("cert") or None
self._default_http3 = kwargs.get("http3", False)
self.selector_config = kwargs.get("selector_config") or {}
self._is_alive = False
self._proxy_rotator: Optional[ProxyRotator] = kwargs.get("proxy_rotator")
if self._proxy_rotator and (self._default_proxy or self._default_proxies):
raise ValueError(
"Cannot use 'proxy_rotator' together with 'proxy' or 'proxies'. "
"Use either a static proxy or proxy rotation, not both."
)
@staticmethod
def _get_param(kwargs: Dict, key: str, default: Any) -> Any:
"""Get parameter from kwargs if present, otherwise return default."""
return kwargs[key] if key in kwargs else default
def _merge_request_args(self, **method_kwargs) -> Dict[str, Any]:
"""Merge request-specific arguments with default session arguments."""
url = method_kwargs.pop("url")
# Get parameters from kwargs or use defaults
impersonate = self._get_param(method_kwargs, "impersonate", self._default_impersonate)
impersonate = _select_random_browser(impersonate)
http3_enabled = self._get_param(method_kwargs, "http3", self._default_http3)
stealth = self._get_param(method_kwargs, "stealth", self._stealth)View on GitHub (pinned to 5d213a2d47)
Solutions
- Remove the 'proxy' (or 'proxies') kwarg and keep only proxy_rotator if you want rotating proxies.
- Or remove proxy_rotator and keep the static 'proxy'/'proxies' kwarg if you want a single fixed proxy.
- If you need a fallback static proxy, encode it as the last entry inside the ProxyRotator's proxy list instead of a separate kwarg.
Example fix
# before session = FetcherSession(proxy='http://10.0.0.1:8080', proxy_rotator=ProxyRotator([...])) # after session = FetcherSession(proxy_rotator=ProxyRotator(['http://10.0.0.1:8080', 'http://10.0.0.2:8080']))
Defensive patterns
Strategy: validation
Validate before calling
from scrapling.engines.proxy import ProxyRotator
def make_static_fetcher(proxy=None, proxies=None, proxy_rotator=None):
if proxy_rotator is not None and (proxy or proxies):
raise ValueError('Choose one: static proxy OR proxy_rotator, not both')
return FetcherSession(proxy=proxy, proxies=proxies, proxy_rotator=proxy_rotator) Type guard
def has_exclusive_proxy_config(proxy, proxies, rotator) -> bool:
return not (rotator is not None and (proxy is not None or proxies is not None)) Try / catch
try:
session = FetcherSession(proxy=proxy, proxy_rotator=rotator)
except ValueError as e:
if 'proxy_rotator' in str(e):
# config conflict: drop the static proxy and rebuild
session = FetcherSession(proxy_rotator=rotator)
else:
raise Prevention
- Keep proxy configuration in one place (a dataclass or config dict) with a single 'mode' field.
- Assert the exclusivity invariant in your own factory before constructing fetchers.
- When migrating to ProxyRotator, grep for 'proxy=' and 'proxies=' to remove leftovers.
When it happens
Trigger: Calling FetcherSession(proxy='http://...', proxy_rotator=rotator), AsyncFetcherSession(proxies={...}, proxy_rotator=rotator), or any static fetcher class (Fetcher/AsyncFetcher) with both kwargs set. Also triggered when a FetcherSession forwards its saved config into an inner _SyncSessionLogic/_ASyncSessionLogic while both fields were somehow populated.
Common situations: Copy-pasting a proxy from an existing scraper while adding the new ProxyRotator feature; migrating from static proxies to rotation and forgetting to delete the old 'proxy' kwarg; passing a dict of proxies that was valid pre-rotator versions.
Related errors
- Invalid proxy string!
- Cannot use 'proxy_rotator' together with 'proxy'. Use either
- Unknown parser argument: "{key}"; maybe you meant {cls.parse
- You must pass a keyword to configure, current keywords: {cls
- The proxy argument's string is in invalid format!
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/b4d9e8760f91a432.
Report an issue: GitHub.