# Handling Impossible Error Scenarios: The Karpathy Code Guidelines Pattern

> Handle impossible error scenarios efficiently. Learn Andrej Karpathy's code guideline pattern to fail fast during development and maintain clean production code. Assert for impossible conditions.

- Repository: [Jiayuan Zhang/andrej-karpathy-skills](https://github.com/forrestchang/andrej-karpathy-skills)
- Tags: best-practices
- Published: 2026-04-08

---

**Omit defensive error handling for logically impossible conditions and instead use assertions or unreachable code markers to fail fast during development, keeping production code minimal and maintainable.**

The `forrestchang/andrej-karpathy-skills` repository establishes a rigorous stance on defensive programming: **do not write error handling for impossible scenarios**. According to the guidelines in [`skills/karpathy-guidelines/SKILL.md`](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/skills/karpathy-guidelines/SKILL.md) (lines 30-31), this principle keeps codebases clean by ensuring that violated assumptions surface immediately as bugs rather than being masked by speculative error handlers.

## Why Avoid Defensive Code for Impossible Scenarios?

The **"Simplicity First"** principle in the Karpathy guidelines explicitly rejects defensive programming for logically unreachable states. This design choice rests on four pillars:

- **Noise reduction** – Guards for conditions that should never occur inflate code size and distract from legitimate business logic.
- **Maintainability** – When a supposedly impossible guard triggers, it signals a genuine bug in underlying assumptions, prompting a proper fix instead of silent failure.
- **Performance** – Eliminating impossible branches removes overhead in tight loops and hot paths.
- **Clarity** – Readers parse only relevant logic flows; they never wade through defensive branches that execute only when the program is already broken.

## The Recommended Pattern for Impossible Scenarios

When facing a logically unreachable code path, follow this three-step protocol:

### Document the Invariant

State the assumption clearly in comments or type contracts. Explicit documentation transforms implicit knowledge into verifiable constraints.

### Assert the Assumption

Use lightweight assertions (`assert`, `debug_assert`, `static_assert`, or language-specific equivalents) that crash immediately during development if the invariant breaks. In [`skills/karpathy-guidelines/SKILL.md`](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/skills/karpathy-guidelines/SKILL.md), the guidelines emphasize that these assertions act as executable documentation.

### Leave the Else Branch Empty

Do not return generic errors, default values, or empty strings. Let the assertion surface the bug. In production builds, assertions can be compiled out or converted to fail-fast guards depending on your configuration.

## Implementation Examples Across Languages

The repository provides language-specific idioms for marking unreachable code. Each example follows the guideline: **assert impossibility rather than handling it**.

### TypeScript and JavaScript

Use explicit `throw` statements or type-system narrowing to mark unreachable branches:

```typescript
function getStatusCode(status: "ok" | "error"): number {
  // We assume `status` is always one of the two literal values.
  // Any other value would indicate a programming mistake.
  if (status === "ok") return 200;
  if (status === "error") return 500;

  // ----------- Impossible case ----------- //
  // This branch should never be reached.
  throw new Error(`Unreachable status value: ${status}`);
}

```

The `throw` acts as a runtime assertion. If `status` ever holds a value outside the declared union, the program fails fast, revealing a true bug rather than silently returning a vague error.

### Python

Raise `AssertionError` for states that violate preconditions:

```python
def process_state(state: str) -> int:
    """Assumes `state` is either 'ready' or 'failed'."""
    if state == "ready":
        return 0
    if state == "failed":
        return 1

    # Impossible case – raise AssertionError to flag a bug.

    raise AssertionError(f"Unexpected state: {state!r}")

```

### Rust

Leverage `unreachable!()` for exhaustive pattern matching:

```rust
fn status_code(status: Status) -> u16 {
    match status {
        Status::Ok => 200,
        Status::Error => 500,
        // The `_` arm is unreachable because `status` is exhaustive.
        _ => unreachable!("Invalid Status variant encountered"),
    }
}

```

The `unreachable!()` macro serves as a compile-time hint that the branch cannot occur under correct logic.

### Go

Use `panic` to expose invariant violations immediately:

```go
func httpStatus(s string) int {
    switch s {
    case "ok":
        return 200
    case "error":
        return 500
    default:
        // This should never happen – panic to expose the bug.
        panic(fmt.Sprintf("unreachable status: %s", s))
    }
}

```

## Alignment with the Karpathy Guidelines

This pattern aligns with the core philosophy documented in [`CLAUDE.md`](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/CLAUDE.md) and [`EXAMPLES.md`](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/EXAMPLES.md):

- **No fallback error handling** – Functions do not guess safe defaults for unknown states.
- **Explicit invariants** – Comments and assertions together document assumptions.
- **Fail-fast behavior** – Exceptions surface immediately during development, forcing correction of underlying logic rather than patching symptoms.

By following this approach, you adhere to the **"Simplicity First"** ethos while maintaining a safety net for debugging.

## Summary

- **Document** all assumptions about impossible states using clear comments or type contracts.
- **Assert** invariants using language-specific mechanisms (`assert`, `unreachable!()`, `panic`) that halt execution when logic errors occur.
- **Fail fast** rather than silently swallowing errors or returning generic defaults when impossible scenarios are encountered.
- **Reference** the canonical guidelines in [`skills/karpathy-guidelines/SKILL.md`](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/skills/karpathy-guidelines/SKILL.md) when implementing this pattern in your own projects.

## Frequently Asked Questions

### When should I use assertions versus throwing standard errors?

**Use assertions** for conditions that should be logically impossible given correct program state. Use standard `throw` or `raise` statements for expected but exceptional runtime conditions (network failures, missing files). In the Karpathy guidelines, assertions mark programmer errors while standard errors handle environmental unpredictability.

### What if an impossible scenario actually occurs in production?

If an "impossible" case triggers in production, the assertion will cause an immediate crash or panic (unless compiled out). This is **intentional**—it exposes a fundamental bug in your assumptions that requires immediate investigation and fixing, rather than allowing corrupted state to propagate silently through the system.

### Are there exceptions to the "no defensive code" rule?

The guidelines make exceptions only for **safety-critical systems** or **security boundaries** where an impossible breach could cause harm. In typical application code, however, the recommendation from [`skills/karpathy-guidelines/SKILL.md`](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/skills/karpathy-guidelines/SKILL.md) stands firm: do not add speculative handling for states that violate your documented invariants.