BerriAI/litellm · error · ValueError
Invalid type for field
Error message
Invalid type for field '{field_name}': expected {getattr(expected_type, '__name__', str(expected_type))}, got {type(value).__name__} What it means
Before rendering, PromptManager._validate_input checks every variable that is present in the payload against the prompt's frontmatter input schema: each declared field's type string is mapped to a Python type ('string'->str, 'number'->(int, float), 'integer'->int, ...) and tested with isinstance. A mismatch raises ValueError naming the field, the expected type, and the actual type. Only fields present in both the schema and the variables are checked; missing fields pass here.
Solutions
- Coerce variables to the schema types before render (int(v) / float(v) / str(v) as appropriate)
- Align the frontmatter input.schema declarations with what callers actually send
- Omit optional fields you cannot type correctly instead of sending wrong-typed values
- Log template.input_schema (manager.prompts[id].input_schema) when the error is unclear
Example fix
# before — schema declares: count: integer
manager.render('report', {'count': '5'})
# after
manager.render('report', {'count': int('5')}) Defensive patterns
Strategy: type-guard
Validate before calling
schema = manager.prompts[prompt_id].input_schema
coerce = {'string': str, 'integer': int, 'number': float}
for field, spec in schema.items():
if field in variables and isinstance(spec, str):
variables[field] = coerce[spec](variables[field])
manager.render(prompt_id, variables) Type guard
def matches_schema_type(value, schema_type: str) -> bool:
mapping = {'string': str, 'str': str, 'integer': int, 'int': int,
'number': (int, float)}
expected = mapping.get(schema_type)
return expected is None or isinstance(value, expected) Try / catch
try:
manager.render(prompt_id, variables)
except ValueError as e:
if 'Invalid type for field' in str(e):
# coerce from strings (common for HTTP input) and retry once
variables = coerce_variables(variables, manager.prompts[prompt_id].input_schema)
manager.render(prompt_id, variables)
else:
raise Prevention
- At API boundaries, convert query-string params to the schema types before they reach prompts
- Keep frontmatter input.schema in sync with what callers send (review on template changes)
- Write one render test per prompt with realistic typed variables
When it happens
Trigger: render('report', {'count': '5'}) when the frontmatter declares count as integer/number; passing a float where 'string' is declared; passing a scalar where the schema expects a list/dict type. Python quirks: bool passes an integer check, and 'number' accepts both int and float.
Common situations: Variables arriving from HTTP query params or JSON strings (everything is a str); a schema updated to integer while callers still send strings; mixing None for optional fields that were declared with a concrete type; unit tests passing literals of the wrong type.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Error rendering template
- Invalid YAML frontmatter
- Prompt directory does not exist
- prompt_id is required when prompt_file is provided
- Prompt ' ' not found. Available prompts
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/41e9e8ee36136306.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/dotprompt/prompt_manager.py:234
self._validate_input(variables, template.input_schema)
try:
# Create Jinja2 template and render
jinja_template: Final = self.jinja_env.from_string(template.content)
rendered: Final = jinja_template.render(**variables)
return rendered
except Exception as e:
raise ValueError(f"Error rendering template '{prompt_id}': {e}")
def _validate_input(self, variables: dict[str, Any], schema: dict[str, Any]) -> None:
"""Basic validation of input variables against schema."""
for field_name, field_type in schema.items():
if field_name in variables:
value = variables[field_name]
expected_type = self._get_python_type(field_type)
if not isinstance(value, expected_type):
raise ValueError(
f"Invalid type for field '{field_name}': "
f"expected {getattr(expected_type, '__name__', str(expected_type))}, got {type(value).__name__}"
)
def _get_python_type(self, schema_type: str) -> type | tuple:
"""Convert schema type string to Python type."""
type_mapping: Final[dict[str, type | tuple]] = {
"string": str,
"str": str,
"number": (int, float),
"integer": int,
"int": int,
"float": float,
"boolean": bool,
"bool": bool,
"array": list,
"list": list,
"object": dict,View on GitHub (pinned to 77b7c6c40c)