aio-libs/aiohttp · error · ValueError

body and text are not allowed together

Error message

body and text are not allowed together

What it means

Response.__init__ accepts body and text as mutually exclusive kwargs. Passing both is contradictory — text is encoded into bytes and becomes the body, so supplying both is ambiguous. The check is at line 554-555.

Source

Thrown at aiohttp/web_response.py:555

    _compressed_body: bytes | None = None
    _send_headers_immediately = False

    def __init__(
        self,
        *,
        body: Any = None,
        status: int = 200,
        reason: str | None = None,
        text: str | None = None,
        headers: LooseHeaders | None = None,
        content_type: str | None = None,
        charset: str | None = None,
        zlib_executor_size: int = MAX_SYNC_CHUNK_SIZE,
        zlib_executor: Executor | None = None,
    ) -> None:
        if body is not None and text is not None:
            raise ValueError("body and text are not allowed together")

        if headers is None:
            real_headers: CIMultiDict[str] = CIMultiDict()
        else:
            real_headers = CIMultiDict(headers)

        if content_type is not None and "charset" in content_type:
            raise ValueError("charset must not be in content_type argument")

        if text is not None:
            if hdrs.CONTENT_TYPE in real_headers:
                if content_type or charset:
                    raise ValueError(
                        "passing both Content-Type header and "
                        "content_type or charset params "
                        "is forbidden"
                    )
            else:

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Pass only one: text for str payloads (auto-encoded with charset) or body for raw bytes.
  2. If you have a str, encode it once and pass body=, or pass text= and drop body=.
  3. Use json_response(data=...) which handles encoding for you.

Example fix

# before
resp = Response(body=payload.encode(), text=payload)  # raises ValueError

# after
resp = Response(text=payload)
Defensive patterns

Strategy: validation

Validate before calling

def make_response(*, body=None, text=None, **kw):
    assert not (body is not None and text is not None), 'pass only one of body or text'
    return Response(body=body, text=text, **kw)

Prevention

When it happens

Trigger: Calling Response(body=b'...', text='...') in the same constructor; programmatically forwarding both when wrapping values into a response; copy-paste that left both fields populated.

Common situations: Building a Response from a dict of optional kwargs where both got set; porting code that previously set body and now also sets text.

Related errors


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