zylon-ai/private-gpt · error · TypeError

REQUEST_TOO_LARGE_ERROR

REQUEST_TOO_LARGE_ERROR

Error message

structured_outputs JSON must decode to an object; got {type(structured_outputs).__name__}

What it means

TypeError raised when the structured_outputs string parsed as valid JSON but decoded to a non-object top-level value (list, string, number, bool, null). The normalizer requires a JSON object because it must map keys like json/json_schema into StructuredOutputsParams fields; arrays or scalars are meaningless there.

Source

Thrown at private_gpt/components/llm/custom/base.py:127

    API serializers use ``json`` instead of the model's internal
    ``json_schema`` field. Normalize those representations before backend
    specific code accesses the typed fields.
    """
    if structured_outputs is None:
        return None
    if isinstance(structured_outputs, StructuredOutputsParams):
        return structured_outputs

    if isinstance(structured_outputs, str):
        try:
            structured_outputs = json.loads(structured_outputs)
        except json.JSONDecodeError as exc:
            raise ValueError(
                "structured_outputs must be a StructuredOutputsParams, "
                "mapping, JSON object string, or None"
            ) from exc
        if not isinstance(structured_outputs, Mapping):
            raise TypeError(
                "structured_outputs JSON must decode to an object; "
                f"got {type(structured_outputs).__name__}"
            )

    if isinstance(structured_outputs, Mapping):
        values = dict(structured_outputs)
        if "json" in values and "json_schema" not in values:
            values["json_schema"] = values.pop("json")
        return StructuredOutputsParams.model_validate(values)

    raise TypeError(
        "structured_outputs must be a StructuredOutputsParams, mapping, "
        "JSON object string, or None; "
        f"got {type(structured_outputs).__name__}"
    )


class SamplingParameters(BaseModel):

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Wrap the schema in an object: use {"json_schema": {...}} not a bare array.
  2. If the string decodes to another string, decode again or stop pre-encoding the payload.
  3. Read the type name in the message (got list / got str) to see exactly what the decode produced.
  4. Pass a StructuredOutputsParams or plain dict to bypass string handling entirely.

Example fix

# before
params = '[{"name": "answer", "type": "object"}]'

# after
params = {"json_schema": {"name": "answer", "type": "object", "schema": {...}}}
Defensive patterns

Strategy: type-guard

Validate before calling

import json
obj = json.loads(structured_outputs) if isinstance(structured_outputs, str) else structured_outputs
if not isinstance(obj, dict):
    raise TypeError(f'structured_outputs root must be an object, got {type(obj).__name__}')

Type guard

from collections.abc import Mapping

def is_structured_outputs_mapping(value: object) -> bool:
    if isinstance(value, str):
        try:
            value = json.loads(value)
        except json.JSONDecodeError:
            return False
    return isinstance(value, Mapping)

Try / catch

try:
    llm.stream_chat(messages, structured_outputs=payload)
except TypeError as e:
    if 'must decode to an object' in str(e):
        payload = {'json_schema': payload[0]}  # unwrap array-wrapped schema

Prevention

When it happens

Trigger: Passing structured_outputs='[{"json_schema": ...}]' (array-wrapped schema) or '"{""json_schema"": ...}"' (still a string after decode) — anything whose decoded root is not a Mapping.

Common situations: Schemas authored as JSON arrays of definitions; double-encoded JSON strings that decode to a str; copying schema fragments from OpenAPI files that root in lists.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/691d1fb2e3aa9cf8. Report an issue: GitHub.