{"record":{"id":"00fb92c2b21000cc","repo":"scrapy/scrapy","slug":"self-class-name-init-received-both","errorCode":null,"errorMessage":"{self.__class__.__name__}.__init__() received both response and text","messagePattern":"(.+?)\\.__init__\\(\\) received both response and text","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapy/selector/unified.py","lineNumber":71,"sourceCode":"\n    .. note:: JSON selector support requires ``parsel`` 1.8.0 or higher. With\n       older versions setting ``type`` to ``\"json\"`` or ``\"text\"`` is not\n       supported.\n    \"\"\"\n\n    __slots__ = [\"response\"]\n    selectorlist_cls = SelectorList\n\n    def __init__(\n        self,\n        response: TextResponse | None = None,\n        text: str | None = None,\n        type: SelectorType | None = None,  # noqa: A002\n        root: Any | None = _NOT_SET,\n        **kwargs: Any,\n    ):\n        if response is not None and text is not None:\n            raise ValueError(\n                f\"{self.__class__.__name__}.__init__() received both response and text\"\n            )\n\n        # A response that is neither HTML nor XML, e.g. a JSON one, keeps type\n        # unset, so that parsel determines it from the body.\n        if type is None:\n            if isinstance(response, XmlResponse):\n                type = \"xml\"  # noqa: A001\n            elif response is None or isinstance(response, HtmlResponse):\n                type = \"html\"  # noqa: A001\n\n        if text is not None:\n            response = _response_from_text(text, type)\n\n        if response is not None:\n            text = response.text\n            kwargs.setdefault(\"base_url\", get_base_url(response))\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/scrapy/scrapy/blob/06af687662112027b4482d31e2714a3cf280a91f/scrapy/selector/unified.py#L53-L89","documentation":"Selector (scrapy.selector.Selector, the unified wrapper over parsel) raises ValueError in __init__ when both response and text are passed. A selector is constructed from exactly one source: a Response object (using its body/encoding) or a raw text string. Supplying both is ambiguous, so it is rejected immediately.","triggerScenarios":"Selector(response=resp, text='<html>...') or Selector(resp, text=html_string); helper functions that default both parameters and forward them unconditionally; copy-pasting shell examples into code with both kwargs filled.","commonSituations":"Wrapping selectors in utility functions where response and text both have defaults; feeding an encoded body string alongside the response for 'safety'; interactive scrapy shell habits carried into production code.","solutions":["Pass only one source: Selector(response=resp) or Selector(text=html_string).","In wrapper functions, branch on which argument is provided before constructing.","For raw bytes from a response, use response.text or let the response construct the selector itself (response.selector)."],"exampleFix":"# before\nsel = Selector(response=response, text=response.text)  # ValueError\n\n# after\nsel = Selector(response=response)","handlingStrategy":"validation","validationCode":"assert not (response is not None and text is not None), \\\n    'Selector accepts either response or text, not both'","typeGuard":null,"tryCatchPattern":"try:\n    sel = Selector(response=response, text=text)\nexcept ValueError:\n    sel = Selector(response=response) if response is not None else Selector(text=text)","preventionTips":["Pass exactly one of response or text.","In wrapper functions, branch on which argument is provided instead of forwarding both.","Prefer response.selector when you already hold the response."],"tags":["scrapy","selector","type-error","validation"],"backgroundTag":null,"analyzedSha":"06af687662112027b4482d31e2714a3cf280a91f","analyzedAt":"2026-08-15T00:21:48.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}