ax-check rule
AXC-D007: Closed vocabulary hinted in prose, not declared as an enum
A parameter description lists allowed values ("one of", "e.g. 'x'", "such as") but the schema declares no enum.
ax-check is a checker being prepared for release. This page documents the rule ahead of that release; see all 50 rules.
| Severity | warn |
| Kind | Heuristic. A pattern match: a prompt to look, not a verdict. |
| Mode | ax-check lint |
| Applies to | MCP tool lists, OpenAPI |
| Pattern tags | schema-enum, description, false-success |
| Fix in one line | Move the allowed values into the schema as "enum" (or "const" alternatives) and keep the prose for meaning. |
A parameter description lists allowed values, with words such as “one of”, “for example ‘draft’” or “such as ‘paid’”, but the schema declares no enum. The agent has to guess the full set from a hint. When it guesses wrong, many servers do not reject the value: they ignore it, and the agent reports success on a call that did nothing useful.
What it checks
For each string parameter, ax-check reads the description for signs of a closed set of values. If it finds one and the schema has no enum, no const and no list of constant alternatives, it reports the parameter.
Why it matters
A schema is checked by machines; prose is not. An enum lets the client validate the call before it is sent and lets the server return an honest error. A vocabulary that lives only in the description is invisible to both.
Li, Ye, Guo and Dang studied this in “SilentProbe” (preprint, August 2026). Across 721,320 parameters in 2,501 OpenAPI documents, the paper’s claim is that 7.5% declare an enumeration, and 40.1% of documents state a constraint in prose that the schema does not encode. In their tests, machine-checkable constraints gave an honest error in 111 of 111 cases, while prose-only constraints failed silently in 44 of 61. With twelve models from eight families, a vocabulary the description merely exemplified was missed on 88 of 88 attempts; promoting it into the schema took the failure to 0 of 89 (all the paper’s claim). The authors reached the endpoints through one aggregation layer with which they declare an affiliation.
How to fix
Move the allowed values into the schema as enum (or as oneOf alternatives that each use const, when each value needs its own description). Keep the prose for meaning: what each value does and what happens when the parameter is omitted.
Example
Before
"status": {
"type": "string",
"description": "Filter by invoice status, for example 'draft' or 'paid'."
}
After
"status": {
"type": "string",
"enum": ["draft", "open", "paid", "void"],
"description": "Only return invoices in this state. Omit it to return invoices in every state."
}
How ax-check detects it
The rule looks only at string-like parameters: no type, type: string, or an array of strings. It skips a parameter that already has enum, const, or oneOf/anyOf where every branch is a const or an enum (and the same for array items). Parameters are the top-level properties of an MCP input schema, and OpenAPI parameters and top-level JSON request body properties. CLI help and skills are not checked by this rule.
Strong signals report the parameter on their own:
- “one of the following”, “any of the following” or “either of the following”;
- “one of”, “any of” or “either of” in other forms, unless followed by a word such as “the”, “your” or “these” (so “one of the invoices” does not count);
- “valid values”, “allowed options”, “supported modes” and similar;
- “options are”, “values include”, “must be one of”, “must be either”;
- two or more quoted words joined by commas, slashes, pipes, “or” or “and”, such as
'draft', 'open' or 'paid'; - a bare pipe list such as
asc|desc.
A weak signal, “e.g.”, “for example”, “for instance”, “such as” or “like” followed by one quoted word, counts only when the parameter name does not look like free input (names ending in query, text, name, id, slug, url, path, email, date, tag and similar) and the schema has no format or pattern. A strong signal that sits just after “for example” is ignored on the same kind of parameter.
Known false negatives: a vocabulary introduced in other words, such as “Accepts draft, open or paid” with unquoted values, is missed. Nested object properties are not inspected.
Known false positives: an open set illustrated with quoted examples, such as a locale parameter described as “for example ‘en-GB’ or ‘fr-FR’”. Adding a pattern or format silences the finding and documents the shape. Otherwise use --disable AXC-D007.
Sources
- Paper: Li, Ye, Guo and Dang, “SilentProbe: Measuring Silent Failure in Production APIs Used as Agent Tools”, arXiv 2609.00035, submitted 29 August 2026 (preprint, not peer reviewed). https://arxiv.org/abs/2609.00035 . The paper’s claim, with twelve models across eight families, is that a vocabulary only exemplified in prose was missed on 88 of 88 attempts and on 0 of 89 once declared in the schema.
- Site guide: Write tool descriptions an agent can act on, agentexperience.tech. https://agentexperience.tech/insights/tool-descriptions/ . Asks for closed sets to be declared in the schema as an enum, with
additionalPropertiesset to false.
Related evidence
Records in the AX evidence register that share a pattern tag with this rule. A shared tag means the record is about the same pattern, not that it tests this rule. Read the evidence class before the number.
- EV-0001: An enum in the schema ends silent failures from example-only vocabularies (Preprint). SilentProbe (preprint) reports that a vocabulary a parameter description only exemplified ("e.g.") was missed on 88 of 88 attempts across twelve models, and that promoting it into the schema cut the failure to 0 of 89.
- EV-0002: Constraints stated only in prose produce silent failures on live APIs (Preprint). SilentProbe (preprint) reports that only 7.5% of 2,501 public OpenAPI documents declare an enum, and that on live endpoints machine-checkable constraints returned an honest error in 111 of 111 cases while prose-only constraints failed silently in 44 of 61.
- EV-0003: Error text that names the next tool lifts recovery (Preprint). A preprint testing five OpenAI models reports that an expired-credential error naming a terminal command left 45% of tasks recovered, naming the server's login tool instead raised recovery to 84%, and on rate limits naming the call to repeat raised recovery from 6% to 88%.
- EV-0004: Naming recovery tools is the active ingredient in failure receipts (Preprint). Outcome Monitors (preprint) reports that receipts naming a violated outcome and the public recovery tools raised ToolMaze completion from 10.9% to 28.1% across four models, and that removing the list of recovery tools eliminated the gain.
- EV-0005: Idempotency keys cut duplicate writes from 28% to 4% (Preprint). LIMBO (preprint) reports that offering an idempotency key on every write cut duplicate side effects from 28% to 4% of episodes because agents use keys when they exist, and that agents reported success in 90% of the episodes in which they had duplicated an effect.
- EV-0006: An evidence contract cuts false-success reports after tool failures (Preprint). Failure-Transparent Agents (preprint) reports that after a required tool failed, six models falsely reported success in 22.8% of responses by default, 9.3% with a transparency instruction and 0.8% with a structured evidence contract.
