{"record":{"id":"41e9e8ee36136306","repo":"BerriAI/litellm","slug":"invalid-type-for-field-field-name-expected-g","errorCode":null,"errorMessage":"Invalid type for field '{field_name}': expected {getattr(expected_type, '__name__', str(expected_type))}, got {type(value).__name__}","messagePattern":"Invalid type for field '(.+?)': expected (.+?), got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/dotprompt/prompt_manager.py","lineNumber":234,"sourceCode":"            self._validate_input(variables, template.input_schema)\n\n        try:\n            # Create Jinja2 template and render\n            jinja_template: Final = self.jinja_env.from_string(template.content)\n            rendered: Final = jinja_template.render(**variables)\n            return rendered\n        except Exception as e:\n            raise ValueError(f\"Error rendering template '{prompt_id}': {e}\")\n\n    def _validate_input(self, variables: dict[str, Any], schema: dict[str, Any]) -> None:\n        \"\"\"Basic validation of input variables against schema.\"\"\"\n        for field_name, field_type in schema.items():\n            if field_name in variables:\n                value = variables[field_name]\n                expected_type = self._get_python_type(field_type)\n\n                if not isinstance(value, expected_type):\n                    raise ValueError(\n                        f\"Invalid type for field '{field_name}': \"\n                        f\"expected {getattr(expected_type, '__name__', str(expected_type))}, got {type(value).__name__}\"\n                    )\n\n    def _get_python_type(self, schema_type: str) -> type | tuple:\n        \"\"\"Convert schema type string to Python type.\"\"\"\n        type_mapping: Final[dict[str, type | tuple]] = {\n            \"string\": str,\n            \"str\": str,\n            \"number\": (int, float),\n            \"integer\": int,\n            \"int\": int,\n            \"float\": float,\n            \"boolean\": bool,\n            \"bool\": bool,\n            \"array\": list,\n            \"list\": list,\n            \"object\": dict,","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/dotprompt/prompt_manager.py#L216-L252","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before — schema declares: count: integer\nmanager.render('report', {'count': '5'})\n\n# after\nmanager.render('report', {'count': int('5')})","handlingStrategy":"type-guard","validationCode":"schema = manager.prompts[prompt_id].input_schema\ncoerce = {'string': str, 'integer': int, 'number': float}\nfor field, spec in schema.items():\n    if field in variables and isinstance(spec, str):\n        variables[field] = coerce[spec](variables[field])\nmanager.render(prompt_id, variables)","typeGuard":"def matches_schema_type(value, schema_type: str) -> bool:\n    mapping = {'string': str, 'str': str, 'integer': int, 'int': int,\n               'number': (int, float)}\n    expected = mapping.get(schema_type)\n    return expected is None or isinstance(value, expected)","tryCatchPattern":"try:\n    manager.render(prompt_id, variables)\nexcept ValueError as e:\n    if 'Invalid type for field' in str(e):\n        # coerce from strings (common for HTTP input) and retry once\n        variables = coerce_variables(variables, manager.prompts[prompt_id].input_schema)\n        manager.render(prompt_id, variables)\n    else:\n        raise","preventionTips":["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"],"tags":["litellm","dotprompt","prompt","schema-validation","type-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}