{"record":{"id":"f9d77632386f4a95","repo":"aio-libs/aiohttp","slug":"only-one-of-data-text-or-body-should-be-specifie","errorCode":null,"errorMessage":"only one of data, text, or body should be specified","messagePattern":"only one of data, text, or body should be specified","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_response.py","lineNumber":752,"sourceCode":"        )\n        self._headers[hdrs.CONTENT_ENCODING] = coding.value\n        self._headers[hdrs.CONTENT_LENGTH] = str(len(self._compressed_body))\n\n\ndef json_response(\n    data: Any = sentinel,\n    *,\n    text: str | None = None,\n    body: bytes | None = None,\n    status: int = 200,\n    reason: str | None = None,\n    headers: LooseHeaders | None = None,\n    content_type: str = \"application/json\",\n    dumps: JSONEncoder = json.dumps,\n) -> Response:\n    if data is not sentinel:\n        if text or body:\n            raise ValueError(\"only one of data, text, or body should be specified\")\n        else:\n            text = dumps(data)\n    return Response(\n        text=text,\n        body=body,\n        status=status,\n        reason=reason,\n        headers=headers,\n        content_type=content_type,\n    )\n\n\ndef json_bytes_response(\n    data: Any = sentinel,\n    *,\n    dumps: JSONBytesEncoder,\n    body: bytes | None = None,\n    status: int = 200,","sourceCodeStart":734,"sourceCodeEnd":770,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_response.py#L734-L770","documentation":"Raised by `aiohttp.web.json_response` when the caller passes both `data=` (the value to be JSON-encoded) and `text=` or `body=`. json_response encodes `data` into a JSON string and assigns it to text; passing text/body too creates an ambiguous source, so it is rejected.","triggerScenarios":"Calling `json_response(data=obj, text='literal')` or `json_response(data=obj, body=b'raw')`. Also triggered by helper wrappers that forward *args/**kwargs and accidentally pass both.","commonSituations":"Conditional handlers that sometimes pre-serialize and sometimes pass the raw object; refactoring that left both arguments wired; copy-pasting a Response() call into json_response() without dropping text/body.","solutions":["Pass exactly one: `data=` for objects to encode, `text=` for an already-encoded JSON string, `body=` for already-encoded bytes.","Use `json_response(data=obj)` in the normal case and let json_response serialize.","For orjson (bytes output) use `aiohttp.web.json_response(data=obj, dumps=lambda d: orjson.dumps(d))` won't work — use the dedicated bytes variant `json_response_with_bytes` or build Response(body=...) directly.","Audit helper signatures to ensure mutually-exclusive kwargs."],"exampleFix":"// before\nreturn json_response(data=payload, text=json.dumps(payload))\n\n// after\nreturn json_response(data=payload)  # json_response does the encoding","handlingStrategy":"validation","validationCode":"def safe_json_response(data=sentinel, text=None, body=None, **kw):\n    if data is not sentinel:\n        assert not (text or body), 'pass only one of data, text, or body'\n    return json_response(data=data, text=text, body=body, **kw)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass exactly one of data=, text=, or body= to json_response.","Let json_response serialize the object — do not pre-encode.","For pre-encoded bytes, use the bytes-encoder variant with body= only.","Audit wrapper signatures for mutually-exclusive kwargs."],"tags":["aiohttp","web-response","json-response","validation"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}