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

  1. Coerce variables to the schema types before render (int(v) / float(v) / str(v) as appropriate)
  2. Align the frontmatter input.schema declarations with what callers actually send
  3. Omit optional fields you cannot type correctly instead of sending wrong-typed values
  4. 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

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


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)