---
name: error-routing
description: Route errors by type, not severity. Use in any workflow with retry or error-handling steps. Maps error classes (transient, semantic, auth, infra, logic, contract) to their correct handlers. Prevents the two most common agent failure modes — retrying logic errors, and ignoring transient failures.
user-invocable: false
model-invocable: true
side-effects: code-edits
permission-profile: normal
triggers:
  - build
  - repair
  - "*"
---

# Error Routing

## Iron Law

```
ROUTE BY CLASS FIRST, SEVERITY SECOND.
NEVER RETRY A LOGIC ERROR.
NEVER ABANDON A TRANSIENT ERROR WITHOUT RETRY.
```

Retrying a logic error wastes time and can cause data corruption. Abandoning a transient error causes false failures. Routing by severity ("it's a 500, must be important") misclassifies both.

## Recognize Your Own Rationalizations

- "It failed, so I'll try a different approach." → Different approach to what? Classify the error first. A different approach to a transient failure is wrong — you need the same approach with a wait.
- "It's a 500 error — must be a server problem." → HTTP 500s include logic errors, auth errors, and transient failures. Read the body.
- "Let me retry with exponential backoff." → Exponential backoff is for transient errors only. Applying it to logic errors just slows down the failure.
- "The test is flaky — I'll just retry it." → Flaky tests are infrastructure errors or race conditions. Classify and fix, don't retry blindly.

## Error Class Taxonomy

### Transient

**Definition:** Will resolve without code change, given time or retry.

**Examples:** network timeout, rate limit (429), service temporarily unavailable (503), lock contention, resource temporarily exhausted.

**Handler:** Retry with wait. Use Retry-After header if present; otherwise exponential backoff (1s, 2s, 4s, max 30s). Max 3 retries. If still failing after 3 retries, escalate to infra error.

**Do NOT:** change code, change approach, or report as a bug.

---

### Auth / Credential

**Definition:** Request rejected due to missing or invalid credentials.

**Examples:** 401, 403, expired token, invalid API key, insufficient permissions.

**Handler:** Do NOT retry. Surface immediately with the exact credential or permission required. Never attempt to infer or work around missing auth — escalate to the human.

**Do NOT:** retry, change approach, or attempt alternative auth methods.

---

### Logic / Contract

**Definition:** Code does the wrong thing. The error is in the logic, not the environment.

**Examples:** wrong output, failing assertion, type error, invariant violation, business rule violation, test failure (not flaky).

**Handler:** Debug, find root cause, fix. State a hypothesis, test that hypothesis, then make the smallest code change that satisfies the contract. Do NOT retry or use a workaround.

**Do NOT:** retry, add a workaround, suppress the error.

---

### Infra / Environment

**Definition:** The execution environment is broken in a way that requires external action.

**Examples:** disk full, out of memory, missing required tool, corrupt DB, missing env var that cannot be inferred.

**Handler:** Surface immediately. Describe exactly what is missing and what the minimum fix is. Do NOT attempt to work around infra failures in code.

**Do NOT:** retry, assume it will resolve, add fallback code.

---

### Semantic / Integration

**Definition:** Two components disagree on a contract — schema mismatch, API version mismatch, unexpected data shape.

**Examples:** JSON parse error on valid-looking response, unexpected null where required, field name changed in dependency.

**Handler:** Investigate the contract. Identify which side is wrong (caller or callee). Fix the contract mismatch, not the symptom.

**Do NOT:** add nil-guards without understanding why the nil is there.

---

### Scope / Ambiguity

**Definition:** Cannot proceed because the task is not well-defined enough to make a correct decision.

**Examples:** conflicting requirements, missing spec, ambiguous acceptance criteria.

**Handler:** Surface the ambiguity with the specific decision that is blocked. Follow `assumption-log` protocol — document the assumption, pick a sensible default, mark for review.

**Do NOT:** guess silently.

## Routing Decision Tree

```
Error occurs
    │
    ├─ Is it a network/rate-limit/timeout?  → TRANSIENT → retry with wait
    │
    ├─ Is it auth/403/401/credential?       → AUTH → surface, do not retry
    │
    ├─ Is it a test failure or wrong output? → LOGIC → debug + fix
    │
    ├─ Is the environment broken?           → INFRA → surface, external action needed
    │
    ├─ Is it a contract/schema mismatch?    → SEMANTIC → investigate contract
    │
    └─ Is the task underspecified?          → SCOPE → assumption-log protocol
```

## Completion Criteria

For each error encountered in the workflow:
- [ ] Error classified by type (not severity)
- [ ] Handler applied per classification
- [ ] Resolution recorded (what the error was, what fixed it)
- [ ] No logic errors suppressed or worked around
- [ ] No transient errors abandoned without retry
