The decision after a validation failure is a classification problem. Before you choose between repair, a fresh call and escalation, answer one question: can the validator point at a specific, bounded defect?
A local failure is one where the defect has an address. A required key is missing, an enum value is not in the list, a number arrived as a string, a date is in the wrong format, a list was truncated before its closing bracket, or the object nested one level too deep. These are the failures schema validation and application-level checks are built to catch, and they are also the failures a model is good at patching when you tell it exactly what went wrong. Valid JSON is not a contract: JSON mode can produce parseable output that still omits required fields or invents enum values, which is why shape validation belongs after generation as well as during it (TrueFoundry on structured outputs).
A global failure is one where the defect has no address because the whole answer is the problem. The model answered a different question, refused the request, lacked the context it needed, or produced reasoning that lands on the wrong conclusion. There is no field to point at, so there is nothing for a repair prompt to correct. You can send the broken output back with "this is wrong" attached, but the model has no bounded target and will usually regenerate from scratch anyway, which is a fresh call wearing a repair pass's costume.
The practical test: if you cannot write the repair instruction as a single sentence naming a field, a value or a span, do not attempt a repair.
A third category is often lumped into "global" but deserves its own branch: the refusal. Modern structured output APIs make safety-based refusals programmatically detectable, so a refusal is not a validation failure at all but a distinct signal you can branch on (OpenAI structured outputs guide). Repeating a refusal with the same prompt tends to produce another refusal, so refusals route to escalation or a fallback path, not to the repair loop.



