run-llama/llama_index · error · ValueError
Unknown schema type {schema_type}
Error message
Unknown schema type {schema_type} What it means
The final else branch of json_schema_to_guidance_output_template: the schema node's 'type' is not one of object/array/string/integer/number/boolean, so the walker has no guidance command to emit and raises ValueError(f"Unknown schema type {schema_type}"). Values like 'null', 'any', or missing/type-less nodes (e.g. pydantic v2 anyOf/Optional unions collapsed by .model_json_schema()) land here.
Source
Thrown at llama-index-core/llama_index/core/prompts/guidance_utils.py:125
)
elif schema["type"] == "string":
if key is None:
raise ValueError("key should not be None")
return "\"{{gen '" + key + "' stop='\"'}}\""
elif schema["type"] in ["integer", "number"]:
if key is None:
raise ValueError("key should not be None")
if use_pattern_control:
return "{{gen '" + key + "' pattern='[0-9\\.]' stop=','}}"
else:
return "\"{{gen '" + key + "' stop='\"'}}\""
elif schema["type"] == "boolean":
if key is None:
raise ValueError("key should not be None")
return "{{#select '" + key + "'}}True{{or}}False{{/select}}"
else:
schema_type = schema["type"]
raise ValueError(f"Unknown schema type {schema_type}")
Model = TypeVar("Model", bound=BaseModel)
def parse_pydantic_from_guidance_program(
response: str, cls: Type[Model], verbose: bool = False
) -> Model:
"""
Parse output from guidance program.
This is a temporary solution for parsing a pydantic object out of an executed
guidance program.
NOTE: right now we assume the output is the last markdown formatted json block
NOTE: a better way is to extract via Program.variables, but guidance does not
support extracting nested objects right now.View on GitHub (pinned to afd0fef371)
Solutions
- Flatten the model: replace Optional/Union fields with a single concrete type (or str with a validator), so every node has a literal 'type' in its schema.
- Remove Any-typed and None-default fields that serialize as typeless/anyOf nodes.
- If the union is genuinely needed, move the guidance program to an object model with simple fields and do the union parsing in your own pydantic validator after extraction.
- Migrate off the guidance integration to a maintained structured-output path (provider JSON mode / function calling).
Example fix
// before
from typing import Optional, Union
from pydantic import BaseModel
class Info(BaseModel):
value: Optional[int] = None # anyOf -> no 'type' -> Unknown schema type
tag: Union[str, int] | None = None
// after
from pydantic import BaseModel, field_validator
class Info(BaseModel):
value: int = 0 # concrete type; default replaces None
tag: str = "" # single type; coerce in a validator if needed
@field_validator("tag", mode="before")
@classmethod
def _cast(cls, v):
return str(v) Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_TYPES = {"object", "array", "string", "integer", "number", "boolean"}
def assert_schema_types_supported(cls) -> None:
schema = cls.model_json_schema()
stack = [schema]
while stack:
node = stack.pop()
if isinstance(node, dict):
if "type" in node and node["type"] not in SUPPORTED_TYPES:
raise TypeError(f"Unsupported schema type {node['type']!r} in {cls.__name__}")
if "anyOf" in node or "allOf" in node or "$ref" in node:
raise TypeError(
f"{cls.__name__} contains anyOf/allOf/$ref nodes; "
"flatten Optional/Union fields to single concrete types."
)
stack.extend(v for v in node.values() if isinstance(v, (dict, list)))
elif isinstance(node, list):
stack.extend(node)
assert_schema_types_supported(Info) Type guard
def is_flat_guidance_schema(cls) -> bool:
"""True when every schema node carries a supported literal 'type'."""
stack = [cls.model_json_schema()]
while stack:
node = stack.pop()
if isinstance(node, dict):
if node.get("type") not in SUPPORTED_TYPES and "type" in node:
return False
if any(k in node for k in ("anyOf", "allOf", "$ref")):
return False
stack.extend(v for v in node.values() if isinstance(v, (dict, list)))
elif isinstance(node, list):
stack.extend(node)
return True Prevention
- Avoid Optional/Union/Any fields in models used with the guidance compiler; pydantic v2 turns Optional into anyOf.
- Validate the model's JSON schema in unit tests before wiring it into GuidancePydanticProgram.
- Keep guidance output models intentionally boring: flat objects of str/int/float/bool/list.
When it happens
Trigger: Passing a pydantic model to GuidancePydanticProgram where some field's JSON schema has no plain 'type': Optional[...] rendered as anyOf, Union types, Any-typed fields, null-typed fields, or a hand-written JSON schema using '$ref'/'allOf' that the walker does not resolve.
Common situations: Pydantic v2 migrations (Optional fields now emit anyOf instead of a nullable type), models with Union or Any fields, or schemas imported from FastAPI/OpenAPI specs. The guidance utility is a shallow schema compiler and only understands a flat type field.
Related errors
- key should not be None
- Must specify root schema for nested object
- Key should not be None
- Failed to parse pydantic object from guidance program. Proba
- Failed to validate query spec. Error: {e}. Got JSON dict: {j
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/5385a9e20790cb80.
Report an issue: GitHub.