Foundations roadmap

Reviewing AI-Generated Code

Log in to save this

Saving keeps this in your list across devices. It's a free account — no card.

In the Review Chamber, Vera the reviewer weighs every piece of code on a set of scales before it goes anywhere near users. Her rule is simple: "If you can't explain it, you can't ship it." AI-generated code is fluent. It is well formatted, it has sensible names, and it looks like it was written by someone who knew what they were doing. That fluency is exactly what makes it easy to skim and approve. Reviewing it properly means reading it as if a stranger wrote it, because one did.

Does it do what was asked?

Start with the task, not the code. Reread what you asked for, then check the code does that, all of it, and nothing else. Common gaps are a requirement quietly dropped ("only active users" never filtered), a slightly different behaviour ("sort by newest" sorted oldest first), or extra features you never wanted.

A useful trick is to write down, before reading, the two or three things the code must do. Then find the lines that do each one. If you can't point at them, they probably aren't there.

Edge cases: empty, missing, huge

Generated code is usually written for the happy path, the input from the example. Your job is to feed it the awkward inputs in your head.

function averageRating(reviews) {
  const total = reviews.reduce((sum, r) => sum + r.rating, 0);
  return total / reviews.length;
}

This looks fine. But with an empty array it returns NaN (0 divided by 0), which then shows up on the page as "NaN stars". If reviews is null it throws. If one review has no rating, the total becomes NaN too. For each input, ask: what happens with nothing, with a missing field, and with a very large amount, say 100,000 items or a 5 MB string?

Error handling and removed checks

Look at what happens when something fails. Is the fetch or database call inside a try, or can one network error crash the whole request? Does a catch block log and carry on as if nothing happened, hiding the failure? Does the user get a useful message?

Then look for what disappeared. When you ask an AI to fix or refactor existing code, compare the old version with the new one. It is common for a rewrite to drop an if that checked permissions, relax a validation rule, or replace a strict comparison with a loose one, simply because the model rewrote the function from scratch. A removed check never shows up as an error. It shows up later as a bug or a security hole.

Needless complexity

AI output is often longer than it needs to be: helper classes for a one-line job, configuration options nobody uses, three layers of abstraction around a single function call. More code means more places for bugs and more to read next time. If a simpler version would do the same job, ask for it, or write it. Simple code is easier for you to review, and so easier to trust.

Read it line by line

Skimming finds nothing. Go through the code one line at a time and, for each line, be able to say what it does and why it is there. When you meet a line you don't understand, stop and find out: look up the function in the docs, run it in isolation, or ask the assistant to explain that specific line.

Before you commit, try Vera's test: explain the code out loud, or in the commit message, to someone who hasn't seen it. What does it do, what inputs does it handle, and how does it fail? If you get stuck, you have found the part you haven't really reviewed yet.

Review is a skill you keep

Reviewing is where the learning happens when you build with AI. Each bug you catch teaches you a pattern, such as empty arrays, missing awaits, or loosened checks, that you will spot faster next time, in AI code and in your own. Letting the AI write and review its own work skips that entirely and leaves you unable to judge the code you are responsible for.

Resources

Curated resources for this node are on the way. Use what you already know how to search for, and check back soon.