{"record":{"id":"1df31894caea9cc4","repo":"D4Vinci/Scrapling","slug":"only-string-values-are-accepted-for-arguments","errorCode":null,"errorMessage":"Only string values are accepted for arguments","messagePattern":"Only string values are accepted for arguments","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"scrapling/parser.py","lineNumber":751,"sourceCode":"                    )\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.\"\n                    )\n\n            else:\n                raise TypeError(f'Argument with type \"{type(arg)}\" is not accepted, please read the docs.')\n\n        if not all([(isinstance(k, str) and isinstance(v, str)) for k, v in kwargs.items()]):\n            raise TypeError(\"Only string values are accepted for arguments\")\n\n        for attribute_name, value in kwargs.items():\n            # Only replace names for kwargs, replacing them in dictionaries doesn't make sense\n            attribute_name = _whitelisted.get(attribute_name, attribute_name)\n            attributes[attribute_name] = value\n\n        # It's easier and faster to build a selector than traversing the tree\n        tags = tags or set(\"*\")\n        for tag in tags:\n            selector = tag\n            for key, value in attributes.items():\n                value = value.replace('\"', r\"\\\"\")  # Escape double quotes in user input\n                # Not escaping anything with the key so the user can pass patterns like {'href*': '/p/'} or get errors :)\n                selector += '[{}=\"{}\"]'.format(key, value)\n            if selector != \"*\":\n                selectors.append(selector)\n\n        if selectors:","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/parser.py#L733-L769","documentation":"Keyword arguments passed to find_all() must have string values, since kwargs are translated into CSS attribute selectors like tag[attr=\"value\"]. A non-string kwarg value (int, bool, list, None) fails the all() check and raises TypeError before any searching starts.","triggerScenarios":"find_all('div', data_count=3), find_all(id=123), or find_all('a', href=None). Note the check applies only to values — keys are Python identifiers and inherently strings.","commonSituations":"Forwarding **kwargs from a config dict or JSON where numbers are parsed as int/float; passing a count limit kwarg that collides with an attribute filter.","solutions":["Stringify values when building kwargs: {'data-count': str(val)}.","For boolean attributes use the string form: find_all('input', disabled='disabled') rather than disabled=True.","Skip None values when forwarding: {k: v for k, v in attrs.items() if v is not None}."],"exampleFix":"# before\nselector.find_all('input', data_count=3)  # TypeError\n\n# after\nselector.find_all('input', data_count='3')","handlingStrategy":"validation","validationCode":"kwargs = {k: str(v) for k, v in kwargs.items() if v is not None}\nselector.find_all('div', **kwargs)","typeGuard":"def kwargs_are_strings(kwargs: dict) -> bool:\n    return all(isinstance(v, str) for v in kwargs.values())","tryCatchPattern":null,"preventionTips":["Stringify all kwarg values coming from config/JSON before forwarding to find_all().","Use the string form for boolean HTML attributes (disabled='disabled')."],"tags":["find-all","kwargs","validation","type-error"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}