headroomlabs-ai/headroom · error · ValueError

Request body is not valid UTF-8 (possibly compressed?): {exc

Error message

Request body is not valid UTF-8 (possibly compressed?): {exc}

What it means

Error "Request body is not valid UTF-8 (possibly compressed?): {exc}" thrown in headroomlabs-ai/headroom.

Source

Thrown at headroom/proxy/helpers.py:2515

async def _read_request_json(request: Request) -> dict[str, Any]:
    """Read and parse JSON from a request, handling compressed bodies.

    Clients like OpenAI Codex may send zstd, gzip, or deflate-compressed
    request bodies.  Starlette's ``request.json()`` does not decompress
    automatically, causing a UnicodeDecodeError on compressed bytes.

    This helper inspects ``Content-Encoding``, decompresses if needed,
    then JSON-decodes the result.  It raises ``ValueError`` on any
    decompression or parse failure so callers can return a clean 400.
    """
    raw = await _read_request_body_bytes(request)

    # Decode and parse JSON
    try:
        text = raw.decode("utf-8")
    except UnicodeDecodeError as exc:
        raise ValueError(f"Request body is not valid UTF-8 (possibly compressed?): {exc}") from exc

    result = json.loads(text)
    if not isinstance(result, dict):
        raise ValueError("Request body must be a JSON object, not " + type(result).__name__)

    # Drop output-only blocks the request schema rejects (see
    # ``strip_output_only_request_blocks``). Callers of this bytes-less reader
    # (e.g. the Gemini path) re-serialize ``result`` themselves.
    if strip_output_only_request_blocks(result.get("messages")):
        logger.warning(
            "removed output-only content block(s) (%s) from request messages "
            "before forwarding (not valid on the request path)",
            ",".join(sorted(OUTPUT_ONLY_REQUEST_BLOCK_TYPES)),
        )

    return result

View on GitHub (pinned to 322425c43b)

Solutions

  1. Check whether the body is actually compressed but missing/incorrect Content-Encoding header — set the correct header on the client
  2. Ensure the client sends UTF-8 encoded JSON
  3. Inspect the underlying decode error {exc} to see where decoding failed

When it happens

Trigger: Raised when a request body cannot be decoded as UTF-8 after decompression, often because it is still compressed or is binary data.

Common situations: See trigger scenarios.


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/35d32f370ef3f4f4. Report an issue: GitHub.