{"record":{"id":"3b7d9c6db35395fe","repo":"run-llama/llama_index","slug":"must-specify-root-schema-for-nested-object","errorCode":null,"errorMessage":"Must specify root schema for nested object","messagePattern":"Must specify root schema for nested object","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/prompts/guidance_utils.py","lineNumber":72,"sourceCode":"\ndef json_schema_to_guidance_output_template(\n    schema: dict,\n    key: Optional[str] = None,\n    indent: int = 0,\n    root: Optional[dict] = None,\n    use_pattern_control: bool = False,\n) -> str:\n    \"\"\"\n    Convert a json schema to guidance output template.\n\n    Implementation based on https://github.com/microsoft/guidance/\\\n        blob/main/notebooks/applications/jsonformer.ipynb\n    Modified to support nested pydantic models.\n    \"\"\"\n    out = \"\"\n    if \"type\" not in schema and \"$ref\" in schema:\n        if root is None:\n            raise ValueError(\"Must specify root schema for nested object\")\n\n        ref = schema[\"$ref\"]\n        model = ref.split(\"/\")[-1]\n        return json_schema_to_guidance_output_template(\n            root[\"$defs\"][model], key, indent, root\n        )\n\n    if schema[\"type\"] == \"object\":\n        out += \"  \" * indent + \"{\\n\"\n        for k, v in schema[\"properties\"].items():\n            out += (\n                \"  \" * (indent + 1)\n                + f'\"{k}\"'\n                + \": \"\n                + json_schema_to_guidance_output_template(v, k, indent + 1, root)\n                + \",\\n\"\n            )\n        out += \"  \" * indent + \"}\"","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/prompts/guidance_utils.py#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ntemplate = json_schema_to_guidance_output_template(schema, \"output\")\n# after\ntemplate = json_schema_to_guidance_output_template(schema, \"output\", 0, schema)\n# schema itself passed as root so $defs can be resolved","handlingStrategy":"validation","validationCode":"import json\nschema = output_cls.model_json_schema()\nhas_refs = \"$ref\" in json.dumps(schema)\n# if has_refs, ensure the converter receives root=schema (or avoid guidance for nested models)","typeGuard":"import json\n\ndef schema_has_nested_refs(output_cls) -> bool:\n    return \"$ref\" in json.dumps(output_cls.model_json_schema())","tryCatchPattern":"try:\n    tmpl = json_schema_to_guidance_output_template(schema, key, indent, schema)\nexcept ValueError as e:\n    if \"root schema\" in str(e):\n        raise RuntimeError(\"flatten nested models before guidance conversion\") from e\n    raise","preventionTips":["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."],"tags":["guidance","json-schema","pydantic","nested-models"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}