D4Vinci/Scrapling · error · TypeError
Invalid proxy type: {type(proxy)}. Expected str or dict.
Error message
Invalid proxy type: {type(proxy)}. Expected str or dict. What it means
Raised during ProxyRotator construction when an element of the `proxies` list is neither a str nor a dict. The rotator iterates the list and type-checks every entry; any other type (None, tuple, nested list, object) is rejected with the offending type in the message.
Source
Thrown at scrapling/engines/toolbelt/proxy_rotation.py:84
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:
raise TypeError(f"Invalid proxy type: {type(proxy)}. Expected str or dict.")
self._current_index = 0
def get_proxy(self) -> ProxyType:
"""Get the next proxy according to the rotation strategy."""
with self._lock:
proxy, self._current_index = self._strategy(self._proxies, self._current_index)
return proxy
@property
def proxies(self) -> List[ProxyType]:
"""Get a copy of all configured proxies."""
return list(self._proxies)
def __len__(self) -> int:
"""Return the total number of configured proxies."""
return len(self._proxies)
View on GitHub (pinned to 5d213a2d47)
Solutions
- Make every entry a proxy URL string or a Playwright-style dict.
- Filter the pool first: pool = [p for p in pool if isinstance(p, (str, dict)) and p].
- Fix the parser that produced the pool so blank/malformed lines are dropped instead of yielded as None.
Example fix
# before
pool = load_lines('proxies.txt') # contains '' and None entries
rotator = ProxyRotator(pool)
# after
pool = [line.strip() for line in open('proxies.txt') if line.strip()]
rotator = ProxyRotator(pool) Defensive patterns
Strategy: type-guard
Validate before calling
clean_pool = [p for p in pool if isinstance(p, (str, dict)) and p]
if len(clean_pool) != len(pool):
log.warning("dropped %d malformed proxy entries", len(pool) - len(clean_pool))
rotator = ProxyRotator(proxies=clean_pool) Type guard
def is_pool_entry(value: object) -> bool:
return isinstance(value, (str, dict)) Try / catch
try:
rotator = ProxyRotator(proxies=pool)
except TypeError as e:
if "Invalid proxy type" in str(e):
pool = [p for p in pool if isinstance(p, (str, dict)) and p]
rotator = ProxyRotator(proxies=pool)
else:
raise Prevention
- Filter blank lines and None when parsing proxy files.
- Never append placeholders (None/0/'') to proxy pools.
- Type-check entries at ingest time, not at rotator construction.
When it happens
Trigger: ProxyRotator(proxies=[None]), proxies=[('http', 'p', 8080)], proxies=[["http://p:8080"]] (nested list), or a pool containing a raw config object.
Common situations: Placeholder entries from parsing blank lines in a proxy file; mixed data from JSON that deserializes tuples as lists; optional proxy slots filled with None.
Related errors
- Invalid proxy string: {proxy_string}
- At least one proxy must be provided
- strategy must be callable, got {type(strategy).__name__}
- Proxy dict must have a 'server' key
- Cannot use 'proxy_rotator' together with 'proxy'. Use either
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/a2134640af859b15.
Report an issue: GitHub.