run-llama/llama_index · error · ValueError

Must specify root schema for nested object

Error message

Must specify root schema for nested object

What it means

json_schema_to_guidance_output_template recursively converts a JSON schema into a guidance template. When it encounters a $ref without a 'type' key, it must look up the definition in the root schema; if root was not passed (None), it cannot resolve nested $refs and raises. The root carries the $defs section holding nested model definitions.

Source

Thrown at llama-index-core/llama_index/core/prompts/guidance_utils.py:72

def json_schema_to_guidance_output_template(
    schema: dict,
    key: Optional[str] = None,
    indent: int = 0,
    root: Optional[dict] = None,
    use_pattern_control: bool = False,
) -> str:
    """
    Convert a json schema to guidance output template.

    Implementation based on https://github.com/microsoft/guidance/\
        blob/main/notebooks/applications/jsonformer.ipynb
    Modified to support nested pydantic models.
    """
    out = ""
    if "type" not in schema and "$ref" in schema:
        if root is None:
            raise ValueError("Must specify root schema for nested object")

        ref = schema["$ref"]
        model = ref.split("/")[-1]
        return json_schema_to_guidance_output_template(
            root["$defs"][model], key, indent, root
        )

    if schema["type"] == "object":
        out += "  " * indent + "{\n"
        for k, v in schema["properties"].items():
            out += (
                "  " * (indent + 1)
                + f'"{k}"'
                + ": "
                + json_schema_to_guidance_output_template(v, k, indent + 1, root)
                + ",\n"
            )
        out += "  " * indent + "}"

View on GitHub (pinned to afd0fef371)

Solutions

  1. Pass the full schema as root when calling json_schema_to_guidance_output_template(schema, key, indent, root=full_schema).
  2. Flatten nested Pydantic models into a single model to avoid $ref resolution.
  3. Upgrade llama-index-core / llama-index-program-guidance — nested-model handling has been improved over releases.

Example fix

# before
template = json_schema_to_guidance_output_template(schema, "output")
# after
template = json_schema_to_guidance_output_template(schema, "output", 0, schema)
# schema itself passed as root so $defs can be resolved
Defensive patterns

Strategy: validation

Validate before calling

import json
schema = output_cls.model_json_schema()
has_refs = "$ref" in json.dumps(schema)
# if has_refs, ensure the converter receives root=schema (or avoid guidance for nested models)

Type guard

import json

def schema_has_nested_refs(output_cls) -> bool:
    return "$ref" in json.dumps(output_cls.model_json_schema())

Try / catch

try:
    tmpl = json_schema_to_guidance_output_template(schema, key, indent, schema)
except ValueError as e:
    if "root schema" in str(e):
        raise RuntimeError("flatten nested models before guidance conversion") from e
    raise

Prevention

When it happens

Trigger: Converting a schema containing $ref entries (nested Pydantic models) while calling the helper without the root argument, or via a code path that recursed before establishing root. Typically reached through GuidancePydanticProgram on models with nested sub-models.

Common situations: Using llama-index-program-guidance (or core guidance utils) with deeply nested Pydantic models; older llama-index versions where root propagation for nested objects was incomplete; custom schemas with $defs references.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/3b7d9c6db35395fe. Report an issue: GitHub.