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

  1. 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.
  2. If you only need plain text back, skip the guidance/structured-program path and call the LLM directly instead of GuidancePydanticProgram.
  3. 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.
  4. 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

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


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