Validate before the API rejects it
A malformed tool schema is a common, frustrating failure: the OpenAI API returns a 400, or worse, the model fills arguments badly because the schema is ambiguous. Paste your tool definition here and get an instant checklist — name format, required fields, parameter types, description quality, and nesting depth — so you catch problems before you ship.
How it works
The validator parses your JSON and runs a set of rules drawn from OpenAI’s
function-calling specification. It accepts either a full tool object
({ "type": "function", "function": { … } }) or just the function definition.
It checks that name is present and uses only allowed characters, that
description exists and isn’t excessively long, that parameters is a proper
JSON Schema object with a properties map, that each property declares a type,
and that nesting stays within a practical depth.
What each check catches
| Rule | What goes wrong without it |
|---|---|
Name format (letters, digits, _, -, 1–64 chars) | API returns 400 with a cryptic error |
description present | Model calls the tool randomly or never |
description not excessively long | Token budget wasted; context window pressure |
parameters.type === "object" | API rejects the tool definition outright |
Each property has a type | Model guesses types; mismatches cause argument errors |
| Nesting depth within practical limit | Deep schemas confuse argument filling; hallucinated keys |
required array present where needed | Optional fields get omitted silently |
Example: a minimal valid schema
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Return the current weather conditions for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city name, for example 'Portland' or 'London'."
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature units to use in the response."
}
},
"required": ["city"]
}
}
}
This passes every check: the name is lowercase alphanumeric, the description is present and concise, parameters is a typed object, each property declares a type, and required lists the mandatory argument.
Common mistakes and how to fix them
Missing parameters object. Some tutorials show a function with no parameters field at all. The API requires the key even when a function takes no arguments — pass { "type": "object", "properties": {} }.
Name with spaces or punctuation. get weather! is invalid. Rename to get_weather. Hyphens are allowed; spaces, dots, and special characters are not.
Property without a type. "city": { "description": "..." } is missing "type": "string". The model may still call the tool, but it cannot infer the expected format without the type field.
Description that is too long. Descriptions over a few hundred characters eat into the context window and crowd out other tools. Aim for one clear sentence per tool, one per parameter.
Tips for reliable tool calling
- Always describe each parameter. The model uses descriptions to decide what to put in each field; vague schemas produce vague calls.
- Mark required fields explicitly in the
requiredarray — otherwise the model may omit them. - Keep it shallow. Flatter schemas with clear enums are filled far more reliably than deeply nested ones.
- Use enums for constrained strings. If a parameter can only be
"asc"or"desc", list both values; the model will pick correctly instead of guessing. - Test with a real prompt. A schema that validates here can still produce bad calls if the descriptions are ambiguous. Always test with a realistic user query before shipping.