A rejection is a single bit. Something downstream said no, and every cause looks identical at the call site. Meanwhile the economics of routing push teams toward cheap models for the bulk of traffic, with a cascade that escalates to a stronger model only when the cheap answer fails a check (TrueFoundry on routing). The danger is that a badly attributed failure turns the cascade into a spend multiplier: you pay the cheap model, you pay the escalation, and you learn nothing about why. As one routing overview puts it, frequent fallbacks add latency and can increase total cost because you pay for the first attempt and the fallback (Merge on routing strategies).
So the first discipline is to stop treating "rejection" as a diagnosis. It is a symptom. The attribution step is what converts an opaque failure rate into a list of causes you can act on.
There is a second reason to be strict here. Judges are prompt-sensitive systems, and identical models produce very different results depending on scoring format, criteria, examples, and information order (Galileo on judge techniques). If your judge is rejecting outputs, the judge's own prompt may be a cause, not the model doing the generating. A taxonomy separates those two failure surfaces.
Three buckets cover nearly every cheap-model rejection you will see in a judge or extractor role. Keep them mutually exclusive in your tagging, because overlapping labels destroy the value of the confusion matrix.
| Bucket | What it looks like | Typical root cause | Usual fix |
|---|---|---|---|
| Format | Invalid JSON, bad escaping, cut off mid-object, extra prose around the payload | No schema enforcement, low output token cap, prompt that invites commentary | Constrained decoding, stricter schema, higher token budget, parser that strips fences |
| Factuality | A value that is wrong, invented, or not supported by the source | Model guess-fills gaps, context too thin, task asks for recall it does not have | Require citations to source spans, abstain option, retrieval improvements |
| Instruction-following | Ignores a stated constraint, fills the wrong field, answers only part of a multi-part request | Ambiguous or overloaded prompt, too many constraints per call | Decompose the prompt, move constraints into the schema, add a checklist eval |
A quick example of why the distinction matters. Suppose a cheap model returns a customer's plan tier as "enterprise" when the account record says "pro." That is factuality. If it returns plan_tier: "Enterprise" with a capital letter and your enum only accepts lowercase, that is format. If it returns the right value in a field called tier when the schema says plan_tier, that is instruction-following. Three different bugs, three different owners, and a model swap fixes at most one of them.
The format bucket deserves special weight because structural fidelity is an operational prerequisite: from the consuming system's perspective, a semantically correct output that violates the expected schema is indistinguishable from a wrong answer (Song et al. on structured output control). That paper also found that strict template-driven generation nearly eliminates syntax errors while structural and semantic errors persist, which is a useful warning: a clean parse does not mean the output is correct.



