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

  1. Pass only data= and let dumps() serialize it.
  2. If you already have a JSON string, pass text= and omit data=.
  3. 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

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


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/f9d77632386f4a95.json. Report an issue: GitHub.