---
title: "Retry a bad answer and then fall back · Agent Wranglers"
url: https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/retry-invalid-output
updated: 2026-10-20
licence: "All rights reserved"
---

# Retry a bad answer and then fall back

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Structured output and tools](https://agentwranglers.se/playbook/ai-features/structured-output-and-tools)
- Rule: When an answer fails validation, retry at most twice with the validation error added, then use a fallback. Never pass an invalid answer on.
- How: Catch the validation error in the gateway. Send the same request again with a short note naming the failed field. After the last retry, return a fallback the feature can handle, such as "unknown", a fixed message or a hand-off to a person. Count failures per prompt version and alert when more than 2 in 100 calls fail, because that points to a prompt or model problem.
- Check: A unit test with a fake provider returns invalid JSON three times. The gateway makes exactly three calls and returns the fallback. The failure counter shows one failed request.

Example:

```ts
const MAX_ATTEMPTS = 3;

export async function generateValid<T>(call: (hint?: string) => Promise<string>, schema: ZodType<T>, fallback: T): Promise<T> {
  let hint: string | undefined;
  for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
    const parsed = schema.safeParse(parseJsonOrUndefined(await call(hint)));
    if (parsed.success) return parsed.data;
    hint = `Your last answer was invalid: ${parsed.error.issues.map(i => `${i.path.join('.')} ${i.message}`).join(', ')}`;
  }
  metrics.increment('ai.invalid_output');
  return fallback;
}
```

```python
MAX_ATTEMPTS = 3

def generate_valid(call: Callable[[str | None], str], schema: type[T], fallback: T) -> T:
    hint = None
    for _ in range(MAX_ATTEMPTS):
        try:
            return schema.model_validate_json(call(hint))
        except ValidationError as error:
            hint = f"Your last answer was invalid: {error.errors(include_input=False)}"
    metrics.increment("ai.invalid_output")
    return fallback
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers ai features playbook: https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/retry-invalid-output`.

- Previous: [Ask for output that matches a schema](https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/schema-output)
- Next: [Give the model a way to say it does not know](https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/allow-unknown)
- [Structured output and tools](https://agentwranglers.se/playbook/ai-features/structured-output-and-tools)
