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
- Pass the full schema as root when calling json_schema_to_guidance_output_template(schema, key, indent, root=full_schema).
- Flatten nested Pydantic models into a single model to avoid $ref resolution.
- 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
- Prefer output models with at most shallow nesting when using guidance-based programs.
- Always pass the full schema as the root argument when calling guidance utils directly.
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
- Key should not be None
- key should not be None
- Unknown schema type {schema_type}
- Failed to parse pydantic object from guidance program. Proba
- There are {len(self.selections)} selections, please use .ind
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/3b7d9c6db35395fe.
Report an issue: GitHub.