D4Vinci/Scrapling · error · TypeError
Nested dictionaries are not accepted, only string keys and s
Error message
Nested dictionaries are not accepted, only string keys and string values are accepted
What it means
A dict passed to find_all() as an attribute filter contained a non-string key or a non-string value. scrapling requires flat Dict[str, str] — nested dicts or dicts with int/list values are rejected with a TypeError because they cannot be translated into a CSS attribute selector.
Source
Thrown at scrapling/parser.py:731
attributes: Dict[str, Any] = dict()
tags: Set[str] = set()
patterns: Set[Pattern] = set()
results, functions, selectors = Selectors(), [], []
# Brace yourself for a wonderful journey!
for arg in args:
if isinstance(arg, str):
tags.add(arg)
elif type(arg) in (list, tuple, set):
arg = cast(Iterable, arg) # Type narrowing for type checkers like pyright
if not all(map(lambda x: isinstance(x, str), arg)):
raise TypeError("Nested Iterables are not accepted, only iterables of tag names are accepted")
tags.update(set(arg))
elif isinstance(arg, dict):
if not all([(isinstance(k, str) and isinstance(v, str)) for k, v in arg.items()]):
raise TypeError(
"Nested dictionaries are not accepted, only string keys and string values are accepted"
)
attributes.update(arg)
elif isinstance(arg, re_Pattern):
patterns.add(arg)
elif callable(arg):
if len(signature(arg).parameters) > 0:
functions.append(arg)
else:
raise TypeError(
"Callable filter function must have at least one argument to take `Selector` objects."
)
else:
raise TypeError(f'Argument with type "{type(arg)}" is not accepted, please read the docs.')
View on GitHub (pinned to 5d213a2d47)
Solutions
- Stringify values: {k: str(v) for k, v in attrs.items()}.
- For multi-valued attributes like class lists, use a regex Pattern as a separate arg: find_all(re.compile(r'\b(a|b)\b')) or loop over each value.
- Unnest nested dicts into separate find_all calls, one attribute set at a time.
Example fix
# before
selector.find_all({'data-count': 3}) # TypeError
# after
selector.find_all({'data-count': '3'}) Defensive patterns
Strategy: type-guard
Validate before calling
attrs = {k: str(v) for k, v in attrs.items() if isinstance(k, str)}
selector.find_all(attrs) Type guard
def is_str_str_dict(d) -> bool:
return isinstance(d, dict) and all(
isinstance(k, str) and isinstance(v, str) for k, v in d.items()
) Prevention
- Normalize attribute-filter dicts from JSON/config by stringifying all values.
- Never nest attribute dicts; split into separate calls.
When it happens
Trigger: find_all({'class': ['a', 'b']}), find_all({'data-count': 3}), or find_all({'attrs': {'id': 'x'}}).
Common situations: Feeding unnormalized JSON/scraped data directly as attribute filters; assuming BeautifulSoup-style tolerance where find_all(attrs={'x': 1}) works.
Related errors
- Nested Iterables are not accepted, only iterables of tag nam
- Argument with type "{type(arg)}" is not accepted, please rea
- Only string values are accepted for arguments
- Response meta should be dictionary but got {type(meta).__nam
- Invalid proxy string: {proxy_string}
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/433677eef0c7a729.
Report an issue: GitHub.