Don't Ship Code You Only Read
What it is
The mistake of accepting AI-generated code because it looks correct on the page — well-structured, sensibly named, plausible logic — and shipping or committing it without actually running it, testing it, or exercising the edge cases. Readable is not the same as working.
Why it works
Claude writes code that reads well by default, and readable code is disproportionately convincing: the naming is clean, the shape is familiar, the logic scans. But the failures that matter — an off-by-one, a wrong API signature, an unhandled null, a subtly inverted condition — are exactly the ones that survive a read-through and only surface when the code runs against real input. Reviewing by eye catches style and obvious logic; running catches behaviour. The fix is to close the loop: execute it, feed it the edge cases, let reality — not plausibility — be the judge.
When to use it
Any generated code you'll actually rely on: something you'll commit, deploy, or build on. Especially code touching data, money, auth, or external APIs, and especially anything with boundary conditions where 'looks right' and 'is right' most often diverge.
When not to use it
Throwaway snippets, illustrative examples, or code you're only reading to understand an approach and will rewrite yourself — there's nothing being shipped, so running it may be more effort than it's worth.
Prompt
Write <the code>. Then, before I trust it: give me a way to verify it actually works — a runnable test or a few concrete inputs with their expected outputs, including the edge cases (empty, boundary, error). Point out the parts most likely to fail at runtime that would still look fine on a read.Example
Claude produces a date-range function that reads perfectly and you nearly commit it. Running it on a range that spans a month boundary returns a negative count — an off-by-one that no amount of re-reading revealed, because the logic looked right. One test against the boundary case caught in seconds what the code review by eye never would have.
Advanced version
Have Claude write the test that would catch its own likely failure before you accept the implementation — name the edge cases, generate a failing-then-passing test, and run it. Pairing generation with verification in the same loop means the code that reaches you has already been exercised, not just written, and you're reviewing behaviour instead of vibes.
Common mistakes
- Equating clean, well-named code with correct code — presentation is not proof.
- Testing only the happy path, so the boundary and error cases where AI code fails go unchecked.
- Committing generated code straight from the chat without running it once against a real input.