aio-libs/aiohttp · error · ValueError
only one of data, text, or body should be specified
Error message
only one of data, text, or body should be specified
What it means
json_response() encodes `data` into text via dumps(). If you also pass text= or body=, the two are contradictory — data already produces the text. The guard at lines 750-752 rejects it.
Source
Thrown at aiohttp/web_response.py:752
)
self._headers[hdrs.CONTENT_ENCODING] = coding.value
self._headers[hdrs.CONTENT_LENGTH] = str(len(self._compressed_body))
def json_response(
data: Any = sentinel,
*,
text: str | None = None,
body: bytes | None = None,
status: int = 200,
reason: str | None = None,
headers: LooseHeaders | None = None,
content_type: str = "application/json",
dumps: JSONEncoder = json.dumps,
) -> Response:
if data is not sentinel:
if text or body:
raise ValueError("only one of data, text, or body should be specified")
else:
text = dumps(data)
return Response(
text=text,
body=body,
status=status,
reason=reason,
headers=headers,
content_type=content_type,
)
def json_bytes_response(
data: Any = sentinel,
*,
dumps: JSONBytesEncoder,
body: bytes | None = None,
status: int = 200,View on GitHub (pinned to c0ef574e29)
Solutions
- Pass only data= and let dumps() serialize it.
- If you already have a JSON string, pass text= and omit data=.
- If you already have bytes, use Response(body=..., content_type='application/json').
Example fix
# before resp = json_response(data=obj, text=json.dumps(obj)) # raises ValueError # after resp = json_response(data=obj)
Defensive patterns
Strategy: validation
Validate before calling
def safe_json_response(data=sentinel, *, text=None, body=None, **kw):
if data is not sentinel and (text or body):
raise ValueError('pass only one of data, text, or body')
from aiohttp import json_response
return json_response(data=data, text=text, body=body, **kw) Prevention
- Pass only data= to json_response; let dumps() serialize.
- For pre-serialized strings use text= and omit data=.
- For pre-serialized bytes use Response(body=..., content_type='application/json').
When it happens
Trigger: Calling json_response(data=obj, text='...') or json_response(data=obj, body=b'...'). `data` defaults to a sentinel so it's only 'set' when explicitly passed.
Common situations: Wrapping json_response and forwarding both a pre-serialized string and the object; copy-paste leaving stale kwargs.
Related errors
- only one of data or body should be specified
- body and text are not allowed together
- Method cannot contain non-token characters {method!r} (found
- Invalid Content-Length header: {content_length_hdr!r}
- compress must be one of True, False, 'deflate', or 'gzip'
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/f9d77632386f4a95.json.
Report an issue: GitHub.