Reviewing AI-Generated Code
AI output still needs a human pass. Spot the planted issues in a real snippet before they ship.
You judge code by whether it runs. That instinct served you fine when you wrote every line yourself and a typo meant an immediate crash. It fails you here: the code in front of you was written by something that produces working syntax by default, and working syntax says nothing about whether the logic underneath it is right.
The mistakes cluster into four shapes
Review enough AI-generated code and the failures stop looking random. The same four shapes come back on a loop, and once you know them you stop reading line by line and start pattern-matching.
It reaches for a package that solves this exact problem elsewhere, and gets the path, the export name, or whether it is even installed wrong — import { debounce } from "lodash-es" when your package.json only has lodash.
A catch block that does nothing, or does something that looks like handling but is not — logs to a console nobody reads, then carries on as though the operation succeeded.
A test that runs the code and checks that it did not throw, not that it produced the right answer. It goes green forever, including the day you break it.
A method that would be reasonable for a language or library to have, and does not, called with total confidence: an array method that does not exist on that type, a config flag from a different major version, a query parameter no endpoint accepts.
async function saveDraft(note) { try { await api.post("/drafts", note); } catch (err) { console.log("save failed"); } return true;}The function returns true whether or not the request succeeded. Nothing downstream can tell a saved draft from a lost one, and the only trace is a console line nobody is watching in production.
Some lines matter more than others
You do not have time to review every line with equal care, and you should not try to. Triage first, in this order.
- 1
Anything touching money, auth, or secrets
A pricing calculation, a permission check, an API key. These are the lines where a subtle mistake costs the most and shows up last.
- 2
The edges
Empty array, zero, null, a network call that fails, an input three orders of magnitude bigger than the example. This is where the off-by-one and the swallowed error live.
- 3
Every new import
Confirm the package is actually a dependency, and that the function it is calling actually exists on it. Ten seconds, and it catches the wrong-import defect outright.
- 4
The tests, last
Read what they assert, not just whether they pass. A test that runs the code and checks nothing is worse than no test — it looks like coverage.
Below is a real snippet with three planted issues, sized to those categories. Find them before you read the explanations.
function calculateAverage(scores) {
const apiKey = ;
let total = 0;
for (let i = 0; i scores.length; i++) {
total += scores[i];
}
return total ;
}
Before you merge, check
- →Readability: could a teammate understand this without you explaining it?
- →Edge cases: empty input, huge input, wrong types, network failure?
- →Security: secrets, unsanitised input, permissions?
- →New dependencies: is this package actually installed, and does it export what's being called?
- →Tests: does anything actually verify this still works?
Key takeaways
- AI-generated code is a draft from a confident stranger. Review it exactly that way, not as a colleague's pull request.
- The mistakes cluster into four repeatable shapes: the wrong import, the swallowed error, the test that asserts nothing, and the invented API.
- Spend your attention on money, auth, secrets, and edges first — that is where a mistake costs the most and hides the longest.
- Take ten seconds to check every new import: is the package installed, and does it export what is being called?
- Anything you cannot explain line by line is not ready to ship, no matter how confidently it was written.
Quick check
Answer these to unlock the next chapter — 3 of 3 to pass. You can retake it anytime.
Answer every question to check.
Make a free account to read on
Every chapter is free — an account is how your progress, XP, and streak follow you from your laptop to your phone, and how you show up on the leaderboard. No payment, no trial.