{"id":"f9e9ce57e36556ba","repo":"aio-libs/aiohttp","slug":"setting-charset-for-application-octet-stream-doesn","errorCode":null,"errorMessage":"Setting charset for application/octet-stream doesn't make sense, setup content_type first","messagePattern":"Setting charset for application/octet-stream doesn't make sense, setup content_type first","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_response.py","lineNumber":240,"sourceCode":"        # Just a placeholder for adding setter\n        return super().content_type\n\n    @content_type.setter\n    def content_type(self, value: str) -> None:\n        self.content_type  # read header values if needed\n        self._content_type = str(value)\n        self._generate_content_type_header()\n\n    @property\n    def charset(self) -> str | None:\n        # Just a placeholder for adding setter\n        return super().charset\n\n    @charset.setter\n    def charset(self, value: str | None) -> None:\n        ctype = self.content_type  # read header values if needed\n        if ctype == \"application/octet-stream\":\n            raise RuntimeError(\n                \"Setting charset for application/octet-stream \"\n                \"doesn't make sense, setup content_type first\"\n            )\n        assert self._content_dict is not None\n        if value is None:\n            self._content_dict.pop(\"charset\", None)\n        else:\n            self._content_dict[\"charset\"] = str(value).lower()\n        self._generate_content_type_header()\n\n    @property\n    def last_modified(self) -> datetime.datetime | None:\n        \"\"\"The value of Last-Modified HTTP header, or None.\n\n        This header is represented as a `datetime` object.\n        \"\"\"\n        return parse_http_date(self._headers.get(hdrs.LAST_MODIFIED))\n","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/web_response.py#L222-L258","documentation":"StreamResponse (and Response) default their content_type to application/octet-stream. The charset setter refuses to attach a charset to this binary type, because a charset parameter is meaningless for opaque binary data and would mislead clients. You must set a meaningful text content_type (e.g. text/plain, application/json) before assigning charset.","triggerScenarios":"Calling `resp.charset = 'utf-8'` on a freshly constructed StreamResponse without first setting content_type, or passing content_type='application/octet-stream' and then assigning charset. The check at line 239 compares ctype == 'application/octet-stream' exactly.","commonSituations":"Devs copy a Response(text=...) example into a manual StreamResponse and try to set charset directly; serving dynamically generated JSON/text as a stream; calling `resp.charset = 'utf-8'` after `StreamResponse()` with no content_type argument.","solutions":["Set a text content_type before charset: resp = StreamResponse(content_type='text/plain') then resp.charset = 'utf-8'.","If you have static text/JSON, use Response(text=...) which auto-sets content_type and charset for you.","If you must override on an existing response, assign resp.content_type = 'application/json' first, then resp.charset."],"exampleFix":"# before\nresp = StreamResponse()\nresp.charset = 'utf-8'  # raises RuntimeError\n\n# after\nresp = StreamResponse(content_type='text/plain')\nresp.charset = 'utf-8'","handlingStrategy":"validation","validationCode":"def safe_set_charset(resp, charset):\n    if resp.content_type == 'application/octet-stream':\n        resp.content_type = 'text/plain'  # or your intended text type\n    resp.charset = charset","typeGuard":"def is_text_content_type(ct: str) -> bool:\n    return not ct.startswith('application/octet-stream') and (\n        ct.startswith('text/') or 'json' in ct or 'xml' in ct or 'charset' in ct\n    )","tryCatchPattern":null,"preventionTips":["Always pass content_type= to StreamResponse when you intend to set charset.","Prefer Response(text=...) for text/JSON bodies — it sets content_type and charset for you.","Never assume the default content_type is a text type; it defaults to application/octet-stream."],"tags":["http","headers","content-type","charset","response"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}