run-llama/llama_index · error · ValueError
key should not be None
Error message
key should not be None
What it means
Raised by llama-index's guidance integration (json_schema_to_guidance_output_template in prompts/guidance_utils.py) when the JSON schema walker hits a 'string' node at a position where no variable key exists (key is None). Guidance programs can only emit a string via a {{gen 'key'}} command, so a top-level bare string schema (e.g. a pydantic model whose root is just str) cannot be compiled into a guidance template. The library assumes real-world structured outputs are objects, so it hard-fails on anything else.
Source
Thrown at llama-index-core/llama_index/core/prompts/guidance_utils.py:110
elif schema["type"] == "array":
if key is None:
raise ValueError("Key should not be None")
if "max_items" in schema:
extra_args = f" max_iterations={schema['max_items']}"
else:
extra_args = ""
return (
"[{{#geneach '"
+ key
+ "' stop=']'"
+ extra_args
+ "}}{{#unless @first}}, {{/unless}}"
+ json_schema_to_guidance_output_template(schema["items"], "this", 0, root)
+ "{{/geneach}}]"
)
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)View on GitHub (pinned to afd0fef371)
Solutions
- Wrap the scalar in a real object model, e.g. `class Out(BaseModel): answer: str` (pydantic) instead of a bare str root, then read `.answer` after parsing.
- If you only need plain text back, skip the guidance/structured-program path and call the LLM directly instead of GuidancePydanticProgram.
- Switch to a structured-output mechanism that supports scalar roots (e.g. an LLM provider with native JSON/function-call output), since guidance support here is deprecated anyway.
- If you must keep the model shape, pre-check the schema root type (see validation) before constructing the program so you fail with your own clearer error.
Example fix
// before
from pydantic import BaseModel
class Answer(BaseModel):
__root__: str # root type 'string' -> ValueError
program = GuidancePydanticProgram(output_class=Answer, ...)
// after
from pydantic import BaseModel
class Answer(BaseModel):
answer: str # root type 'object' -> template compiles
program = GuidancePydanticProgram(output_class=Answer, ...)
result = program(...).answer Defensive patterns
Strategy: validation
Validate before calling
from pydantic import BaseModel
def assert_guidance_compatible(cls: type[BaseModel]) -> None:
schema = cls.model_json_schema() # pydantic v2; .schema() on v1
if schema.get("type") != "object":
raise TypeError(
f"{cls.__name__} has root type {schema.get('type')!r}; "
"GuidancePydanticProgram requires an object-rooted model "
"(wrap scalars in a named field)."
)
assert_guidance_compatible(Answer) # run before building the program Type guard
def is_object_rooted_model(cls) -> bool:
"""True when cls compiles to a guidance-compatible object schema."""
try:
schema = cls.model_json_schema()
except Exception:
return False
return schema.get("type") == "object" Prevention
- Always wrap scalar outputs in a named pydantic field instead of using __root__/RootModel for guidance programs.
- Add a startup assertion on model_json_schema()['type'] == 'object' before constructing GuidancePydanticProgram.
- Prefer provider-native structured output over the deprecated guidance integration for new code.
When it happens
Trigger: Calling GuidancePydanticProgram (or anything that builds a guidance template from a pydantic model) with an output_class whose JSON schema root type is 'string' — e.g. `class Out(BaseModel): __root__: str` in pydantic v1 or a RootModel[str] in v2. The recursive schema compiler is invoked with key=None at the root, hits schema['type'] == 'string', and raises.
Common situations: Migrating a simple prompt that used to return raw text to a 'structured' pydantic output, defining a wrapper model that is just a single string field at the root, or passing List[str]-style roots that nest down to bare scalars. Also appears with older guidance versions where llama-index's guidance support was only ever tested against object models.
Related errors
- Unknown schema type {schema_type}
- StructuredLLM expected a {self.output_cls.__name__} instance
- StructuredLLM expected a {self.output_cls.__name__} instance
- Must specify root schema for nested object
- Key should not be None
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/0e328f5517309bba.
Report an issue: GitHub.