{"record":{"id":"1955cdb94cd2a459","repo":"aio-libs/aiohttp","slug":"text-argument-must-be-str-r","errorCode":null,"errorMessage":"text argument must be str (%r)","messagePattern":"text argument must be str \\(%r\\)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_response.py","lineNumber":576,"sourceCode":"            real_headers: CIMultiDict[str] = CIMultiDict()\n        else:\n            real_headers = CIMultiDict(headers)\n\n        if content_type is not None and \"charset\" in content_type:\n            raise ValueError(\"charset must not be in content_type argument\")\n\n        if text is not None:\n            if hdrs.CONTENT_TYPE in real_headers:\n                if content_type or charset:\n                    raise ValueError(\n                        \"passing both Content-Type header and \"\n                        \"content_type or charset params \"\n                        \"is forbidden\"\n                    )\n            else:\n                # fast path for filling headers\n                if not isinstance(text, str):\n                    raise TypeError(\"text argument must be str (%r)\" % type(text))\n                if content_type is None:\n                    content_type = \"text/plain\"\n                if charset is None:\n                    charset = \"utf-8\"\n                real_headers[hdrs.CONTENT_TYPE] = content_type + \"; charset=\" + charset\n                body = text.encode(charset)\n                text = None\n        elif hdrs.CONTENT_TYPE in real_headers:\n            if content_type is not None or charset is not None:\n                raise ValueError(\n                    \"passing both Content-Type header and \"\n                    \"content_type or charset params \"\n                    \"is forbidden\"\n                )\n        elif content_type is not None:\n            if charset is not None:\n                content_type += \"; charset=\" + charset\n            real_headers[hdrs.CONTENT_TYPE] = content_type","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_response.py#L558-L594","documentation":"Raised by the Response constructor when `text` is provided but is not a str instance (e.g. bytes, int, None-ish sentinel that bypassed the None check, a custom __str__ object). The constructor needs to call `text.encode(charset)`, which only works on str. Passing bytes defeats the purpose of `text=` (use `body=` instead).","triggerScenarios":"Passing `Response(text=b'hello')` (bytes), `Response(text=42)`, or `Response(text=some_object)` where the object is not a str. Common when a JSON serializer returns bytes (orjson) and the result is forwarded as text.","commonSituations":"Using orjson/mujson/ujso which return bytes and passing the encoded output to `text=` instead of `body=`. Forwarding an int/float status or computed value. Helpers that accept `Union[str, bytes]` and forward both to `text=`.","solutions":["If the payload is already bytes, use `body=`: `Response(body=orjson.dumps(data), content_type='application/json')`.","If you have bytes that represent text, decode first: `Response(text=b'hi'.decode('utf-8'))`.","Coerce known types: `Response(text=str(value))` only when you genuinely mean the string form.","Use `aiohttp.web.json_response(data=data)` which handles encoding internally."],"exampleFix":"// before\nreturn Response(text=orjson.dumps(payload))  # bytes -> TypeError\n\n// after\nreturn Response(body=orjson.dumps(payload), content_type='application/json')","handlingStrategy":"type-guard","validationCode":"def coerce_text(text):\n    if isinstance(text, bytes):\n        return text.decode('utf-8')\n    if not isinstance(text, (str, type(None))):\n        return str(text)\n    return text\n\nreturn Response(text=coerce_text(value))","typeGuard":"def is_str_text(text) -> bool:\n    return text is None or isinstance(text, str)","tryCatchPattern":null,"preventionTips":["Use body= for pre-encoded bytes (e.g. orjson output).","Decode bytes to str before passing to text=.","For JSON, prefer json_response() which handles encoding.","Type-annotate helpers so mypy catches non-str text early."],"tags":["aiohttp","web-response","constructor","text","type-error"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}