{"record":{"id":"b6f7028d426557b4","repo":"D4Vinci/Scrapling","slug":"nested-iterables-are-not-accepted-only-iterables","errorCode":null,"errorMessage":"Nested Iterables are not accepted, only iterables of tag names are accepted","messagePattern":"Nested Iterables are not accepted, only iterables of tag names are accepted","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"scrapling/parser.py","lineNumber":726,"sourceCode":"            return Selectors()\n\n        if not args and not kwargs:\n            raise TypeError(\"You have to pass something to search with, like tag name(s), tag attributes, or both.\")\n\n        attributes: Dict[str, Any] = dict()\n        tags: Set[str] = set()\n        patterns: Set[Pattern] = set()\n        results, functions, selectors = Selectors(), [], []\n\n        # Brace yourself for a wonderful journey!\n        for arg in args:\n            if isinstance(arg, str):\n                tags.add(arg)\n\n            elif type(arg) in (list, tuple, set):\n                arg = cast(Iterable, arg)  # Type narrowing for type checkers like pyright\n                if not all(map(lambda x: isinstance(x, str), arg)):\n                    raise TypeError(\"Nested Iterables are not accepted, only iterables of tag names are accepted\")\n                tags.update(set(arg))\n\n            elif isinstance(arg, dict):\n                if not all([(isinstance(k, str) and isinstance(v, str)) for k, v in arg.items()]):\n                    raise TypeError(\n                        \"Nested dictionaries are not accepted, only string keys and string values are accepted\"\n                    )\n                attributes.update(arg)\n\n            elif isinstance(arg, re_Pattern):\n                patterns.add(arg)\n\n            elif callable(arg):\n                if len(signature(arg).parameters) > 0:\n                    functions.append(arg)\n                else:\n                    raise TypeError(\n                        \"Callable filter function must have at least one argument to take `Selector` objects.\"","sourceCodeStart":708,"sourceCodeEnd":744,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/parser.py#L708-L744","documentation":"Inside find_all(), an iterable argument (list/tuple/set) contained at least one non-string element. scrapling only accepts flat iterables of tag names — a nested list, or a list containing ints/Patterns/Selectars, triggers this TypeError before any tree traversal happens.","triggerScenarios":"find_all([['div', 'span'], 'p']), find_all(['div', 42]), or find_all((name for name in names)) where the generator yields non-strings.","commonSituations":"Flattening logic that missed a level of nesting; mixing tag names with regex Patterns in one list instead of passing the Pattern as a separate argument.","solutions":["Flatten the iterable first: itertools.chain.from_iterable(nested) or a small flatten helper.","Keep regex Patterns out of lists — pass them as standalone args: find_all(['div'], re.compile(r'h\\d')).","Coerce everything to str up front if the list mixes str and int from external data: [str(x) for x in items]."],"exampleFix":"# before\nselector.find_all([['div', 'span'], 'p'])  # TypeError\n\n# after\nfrom itertools import chain\nselector.find_all(list(chain.from_iterable([['div', 'span'], ['p']])))","handlingStrategy":"validation","validationCode":"from itertools import chain\n\ndef flatten_tags(items):\n    flat = chain.from_iterable(x if isinstance(x, (list, tuple, set)) else [x] for x in items)\n    return [t for t in flat if isinstance(t, str)]\n\nselector.find_all(flatten_tags(nested_tags))","typeGuard":"def is_flat_str_iterable(items) -> bool:\n    return all(isinstance(x, str) for x in items)","tryCatchPattern":"try:\n    selector.find_all(tags_arg)\nexcept TypeError as e:\n    if 'Nested Iterables' in str(e):\n        tags_arg = list(chain.from_iterable(tags_arg))\n        results = selector.find_all(tags_arg)\n    else:\n        raise","preventionTips":["Flatten iterables of tag names at the boundary where they enter your code.","Keep regex Patterns and callables as separate find_all args, never inside lists."],"tags":["find-all","validation","type-error"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}