Back to notes

October 1, 2026 · 6 min read

I Stopped Reviewing AI-Generated Code Like It's Human-Written

Human code fails loudly in ways you've learned to spot. AI-generated code fails quietly, confidently, and in a completely different shape — so I changed how I review it.

AI EngineeringCode ReviewLLMs

A junior engineer's bad code usually looks bad. Missing error handling is obviously missing. A function that's clearly copy-pasted from Stack Overflow still has the tell-tale signs — inconsistent style, a variable name that doesn't match the rest of the file, a comment that references a different problem than the one it's solving. You learn to spot these patterns fast, and most review checklists are built around catching them.

AI-generated code doesn't fail that way. It fails confidently, in the house style, with consistent naming, and with a plausible-looking comment explaining exactly why the (wrong) approach was taken. The tells that work for catching a junior engineer's mistakes are almost useless here, because the model isn't making a junior engineer's mistakes — it's making a different category of error entirely.

The three failure modes I actually see

  • Hallucinated APIs — a method or parameter that doesn't exist on the library being used, written with total confidence and correct-looking syntax. Compiles fine until it doesn't; in dynamically typed code it fails at runtime, sometimes only on an edge-case input path.
  • Silently dropped edge cases — a refactor that correctly handles the happy path shown in the prompt or nearby code, but quietly drops an error-handling branch or null check that existed in the original and wasn't mentioned in the instruction.
  • Plausible-wrong algorithms — code that implements a real, named, technically correct-sounding approach, just not the one that's actually right for this specific case. It reads like someone who knows the vocabulary but hasn't verified the fit.
Human code that's wrong usually looks uncertain. AI code that's wrong usually looks finished.

What changed in how I review

First: I stopped trusting fluent style as a correctness signal. A clean, idiomatic diff used to correlate reasonably well with a developer who knew what they were doing. That correlation is gone — the model produces clean, idiomatic style regardless of whether the underlying logic is right, so style tells you almost nothing about correctness anymore.

Second: I actually run the code and check referenced APIs exist, every time, even for small diffs — because the hallucinated-API failure mode specifically produces things that look right in a visual diff review and only reveal themselves at execution. A five-minute "did this actually run" check catches a category of bug that careful reading alone won't.

Third: for any refactor or edit to existing code, I diff against what was there before and specifically look for removed branches, not just added ones. Reviewing only the new code misses the silently-dropped-edge-case failure mode entirely, since the bug is an absence, not a presence.

Old review instinct:          New review instinct:
─────────────────────         ─────────────────────
Does the style look clean?    Does every referenced API actually exist?
Does the diff look complete?  What got silently removed, not just added?
Trust fluent explanations     Run it. Fluent ≠ correct.

None of this means AI-assisted code is worse than human code on average — in my experience it's usually faster to a working first draft, especially for boilerplate. It means the review process built for one failure distribution doesn't transfer cleanly to a tool with a different one, and pretending otherwise is how confidently-wrong code ends up in production.