{"record":{"id":"4ac251e5b76b6334","repo":"D4Vinci/Scrapling","slug":"content-argument-must-be-str-or-bytes-got-type-c","errorCode":null,"errorMessage":"content argument must be str or bytes, got {type(content)}","messagePattern":"content argument must be str or bytes, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"scrapling/parser.py","lineNumber":139,"sourceCode":"        self.url = url\n        self._raw_body: str | bytes = \"\"\n        self.encoding = encoding\n        self.__keep_cdata = keep_cdata\n        self.__huge_tree_enabled = huge_tree\n        self.__keep_comments = keep_comments\n        # For selector stuff\n        self.__text: Optional[TextHandler] = None\n        self.__attributes: Optional[AttributesHandler] = None\n        self.__tag: Optional[str] = None\n        self._storage: Optional[StorageSystemMixin] = None\n        if root is None:\n            body: str | bytes\n            if isinstance(content, str):\n                body = content.strip().replace(\"\\x00\", \"\") or \"<html/>\"\n            elif isinstance(content, bytes):\n                body = content.replace(b\"\\x00\", b\"\")\n            else:\n                raise TypeError(f\"content argument must be str or bytes, got {type(content)}\")\n\n            # https://lxml.de/api/lxml.etree.HTMLParser-class.html\n            _parser_kwargs: Dict[str, Any] = dict(\n                recover=True,\n                remove_blank_text=True,\n                remove_comments=(not keep_comments),\n                encoding=encoding,\n                compact=True,\n                huge_tree=huge_tree,\n                default_doctype=True,  # Supported by lxml but missing from stubs\n                strip_cdata=(not keep_cdata),\n            )\n            parser = HTMLParser(**_parser_kwargs)\n            self._root = cast(HtmlElement, fromstring(body or \"<html/>\", parser=parser, base_url=url or \"\"))\n            self._raw_body = content\n\n        else:\n            self._root = cast(HtmlElement, root)","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/parser.py#L121-L157","documentation":"TypeError from Selector.__init__ when `content` is provided but is neither str nor bytes (and `root` is None). The parser only accepts string or bytes HTML bodies; any other type (None, int, dict, an etree element passed via content instead of root) is rejected.","triggerScenarios":"Selector(content=123), Selector(content={'html': '...'}), Selector(content=etree_element) (should use root=), or Selector(content=response) passing the whole response object.","commonSituations":"Passing an already-parsed lxml element through the wrong parameter; JSON APIs returning HTML nested in a dict; passing a Response object where .content was intended; numeric/None defaults leaking from config.","solutions":["Pass the HTML as str or bytes: Selector(content='<div>x</div>') or Selector(content=b'<div>x</div>').","For lxml elements use the root= parameter, which takes priority.","Extract the right field first: Selector(content=response.content)."],"exampleFix":"# before\nsel = Selector(content=response)  # Response object, not HTML\n\n# after\nsel = Selector(content=response.content)  # str/bytes HTML","handlingStrategy":"type-guard","validationCode":"assert isinstance(content, (str, bytes)), f\"content must be str/bytes, got {type(content).__name__}\"\nsel = Selector(content=content)","typeGuard":"def is_html_content(value: object) -> bool:\n    return isinstance(value, (str, bytes))","tryCatchPattern":"try:\n    sel = Selector(content=body)\nexcept TypeError as e:\n    if \"str or bytes\" in str(e):\n        sel = Selector(content=str(body))  # last-resort coercion\n    else:\n        raise","preventionTips":["Pass lxml elements via root=, never content=.","Extract .content/.text from response objects before constructing a Selector.","Type-check at the boundary where external data enters your parsing layer."],"tags":["parser","selector","type-error","validation"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}