{"record":{"id":"3154592a1005157a","repo":"psf/requests","slug":"cookie-headers-should-be-added-with-add-unredirect","errorCode":null,"errorMessage":"Cookie headers should be added with add_unredirected_header()","messagePattern":"Cookie headers should be added with add_unredirected_header\\(\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"warning","filePath":"src/requests/cookies.py","lineNumber":91,"sourceCode":"                parsed.path,\n                parsed.params,\n                parsed.query,\n                parsed.fragment,\n            ]\n        )\n\n    def is_unverifiable(self) -> bool:\n        return True\n\n    def has_header(self, name: str) -> bool:\n        return name in self._r.headers or name in self._new_headers\n\n    def get_header(self, name: str, default: str | None = None) -> str | None:\n        return self._r.headers.get(name, self._new_headers.get(name, default))  # type: ignore[return-value]\n\n    def add_header(self, key: str, val: str) -> None:\n        \"\"\"cookiejar has no legitimate use for this method; add it back if you find one.\"\"\"\n        raise NotImplementedError(\n            \"Cookie headers should be added with add_unredirected_header()\"\n        )\n\n    def add_unredirected_header(self, name: str, value: str) -> None:\n        self._new_headers[name] = value\n\n    def get_new_headers(self) -> dict[str, str]:\n        return self._new_headers\n\n    @property\n    def unverifiable(self) -> bool:\n        return self.is_unverifiable()\n\n    @property\n    def origin_req_host(self) -> str:\n        return self.get_origin_req_host()\n\n    @property","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/psf/requests/blob/8068356288978c4f54661ae6f95afe0e0831885e/src/requests/cookies.py#L73-L109","documentation":"Raised by MockRequest.add_header (the shim used by requests.cookies to bridge to urllib3/http.cookiejar). The cookiejar machinery calls add_header for certain operations, but requests manages cookie headers exclusively via add_unredirected_header, so this method intentionally refuses. It exists purely to redirect maintainers to the correct API.","triggerScenarios":"Calling .add_header(key, val) on the MockRequest object that requests wraps around each PreparedRequest when feeding cookies through a CookieJar; internal cookiejar flows that route through add_header when the cookie policy triggers a header-set path.","commonSituations":"Monkey-patching or instrumenting cookie handling and accidentally hitting add_header; downstream libraries that operate on http.cookiejar.CookieJar abstractions and assume add_header works; a fork or fork-equivalent that wires its own cookie policy.","solutions":["Call add_unredirected_header(name, value) instead of add_header(key, val) when adding cookie headers to a requests MockRequest.","If you are managing cookies at the user level, set them via the session's cookies jar (session.cookies.set(name, value)) or pass the cookies= dict to request(), which routes through the correct API.","If the call comes from inside cookiejar internals, report it upstream; the message itself invites you to add the method back if you find a legitimate use."],"exampleFix":"// before\nmock_request.add_header('Cookie', 'sid=abc')\n\n// after\nmock_request.add_unredirected_header('Cookie', 'sid=abc')","handlingStrategy":"validation","validationCode":"# This is internal API; user-level code should not call add_header on the MockRequest.\n# Validate at the cookie-management level instead:\nfrom http.cookiejar import CookieJar\n\ndef safe_set_cookie(jar, name, value, domain=None, path='/'):\n    assert isinstance(jar, CookieJar)\n    jar.set_cookie(create_cookie(name=name, value=value, domain=domain, path=path))","typeGuard":"# Low-level guard if you must handle a MockRequest-like object:\nfrom typing import Protocol\n\nclass HasUnredirectedHeader(Protocol):\n    def add_unredirected_header(self, name: str, value: str) -> None: ...\n\ndef is_mock_request(obj) -> bool:\n    return hasattr(obj, 'add_unredirected_header') and hasattr(obj, 'get_new_headers')","tryCatchPattern":"# Not typically caught; prefer to avoid calling add_header at all.\n# If integrating with code that may call add_header, wrap it:\ntry:\n    obj.add_header(k, v)\nexcept NotImplementedError:\n    obj.add_unredirected_header(k, v)","preventionTips":["Never call add_header on requests' internal MockRequest; use add_unredirected_header.","Manage cookies through session.cookies / the cookies= argument, not low-level header injection.","If you maintain a cookie policy subclass, override add_unredirected_header rather than add_header."],"tags":["cookies","cookiejar","notimplemented","headers","http"],"backgroundTag":null,"analyzedSha":"8068356288978c4f54661ae6f95afe0e0831885e","analyzedAt":"2026-08-11T20:11:09.238Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}