Handling Impossible Error Scenarios: The Karpathy Code Guidelines Pattern
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 (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, 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:
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:
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:
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:
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 and 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.mdwhen 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 stands firm: do not add speculative handling for states that violate your documented invariants.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →