How to Review AI-Generated Code Before You Trust It in Production

··12 min read
How to Review AI-Generated Code Before You Trust It in Production

Last month I watched a junior developer merge a pull request that an AI assistant had written in about ninety seconds. The code passed the tests. It looked clean. Two days later it deleted 4,000 rows from a production table because the AI had "helpfully" removed a WHERE clause it decided was redundant. Nobody caught it, because nobody actually read the diff. They trusted the machine.

Here's the uncomfortable stat that should keep you honest: a 2024 GitClear analysis of 153 million changed lines of code found that AI-assisted development has driven a measurable rise in "code churn" and copy-pasted blocks, while a Stanford study found developers with AI assistants wrote less secure code but felt more confident it was correct. That confidence gap is exactly where production incidents live.

This article is a practical field guide to review AI-generated code before it ever touches a live system. I'll walk you through a repeatable review process, a worked example with real numbers, a comparison of review approaches, and the specific red flags that separate "ship it" from "absolutely not." No fear-mongering. Just the checklist I actually use.

Key Takeaways
  • Read every line yourself. AI-generated code that passes tests is not the same as correct code. Tests only cover what you thought to test.
  • Assume the AI hallucinated something. Fake package names, invented API methods, and made-up config keys are common and dangerous.
  • Trace data flow, not just logic. The riskiest bugs are silent: missing filters, dropped validation, over-broad permissions.
  • Run static analysis and dependency scanning as a gate, not an afterthought.
  • Verify every new dependency the AI adds before it enters your lockfile.
  • Budget review time. AI writes fast, but reviewing well takes roughly the same time it always did.

Why AI-Generated Code Needs a Different Kind of Review

Reviewing a colleague's code and reviewing an AI's output are not the same task. A human teammate has context, intent, and accountability. They remember the meeting where you decided IDs are UUIDs, not integers. An AI model has none of that. It produces text that is statistically likely to look like working code, which is a very different thing from code that is correct for your system.

This distinction matters because the failure modes are different too. Human bugs tend to be logical mistakes. AI bugs tend to be confident fabrications: an import for a library that doesn't exist, a function signature that was true in version 2 but broke in version 3, or a security control quietly dropped because the training data averaged it away.

I've written before about how AI coding tools make you faster but not ship sooner, and the review step is precisely why. The speed gain at generation gets clawed back at verification. If you skip verification, you're not shipping faster. You're shipping debt.

The three categories of AI code risk

  • Correctness risk: The code does something subtly different from what you asked. Off-by-one errors, wrong comparison operators, inverted booleans.
  • Security risk: Missing input validation, SQL built by string concatenation, secrets logged in plaintext, over-permissive CORS.
  • Supply-chain risk: New dependencies the AI pulled in, some of which may not exist, may be typosquats, or may be abandoned.

A Step-by-Step Process to Review AI-Generated Code

Here is the exact sequence I follow. It takes discipline, not genius. The whole point is that it's boring and repeatable, so you don't skip steps when you're tired at 6 PM on a Friday.

  1. Read the prompt and the output side by side. Before touching the code, re-read what you actually asked for. Does the output solve that, or a nearby problem the model preferred to solve?
  2. Read every changed line, top to bottom. No skimming. If the diff is too large to read carefully, it's too large to trust. Break it up.
  3. Flag every external reference. Each import, package, API call, and environment variable gets a checkmark only after you confirm it's real and current.
  4. Trace the data flow. Follow untrusted input from entry point to storage or output. Note every place validation, sanitization, or authorization should exist and confirm it does.
  5. Check error handling. AI loves the happy path. What happens when the network call times out, the file is missing, or the input is an empty string?
  6. Run static analysis and linters. ESLint, Ruff, gosec, Bandit, whatever fits your stack. Treat warnings as blockers until you've explained each one.
  7. Scan dependencies. Run npm audit, pip-audit, or Trivy against any new packages. Cross-reference with my guide on vetting open source tools for supply-chain attacks.
  8. Write an adversarial test. Not a happy-path test the AI would pass. A test designed to break the assumption you're most worried about.
  9. Run it in staging with real-shaped data. Synthetic "foo/bar" data hides the bugs that only appear with production-shaped inputs.

Where developers cut corners (and pay for it)

The two steps people skip most often are 4 and 8: tracing data flow and writing adversarial tests. They're the least fun and the most valuable. If you only add one habit from this article, make it writing one test that tries to break the AI's code before you approve it.

A Worked Example: Reviewing an AI-Written API Endpoint

Let's make this concrete. Say you asked an AI to write a Node.js endpoint that fetches a user's orders. It hands you 34 lines that look perfectly reasonable. Here's the review in real numbers.

The endpoint accepts a userId from the request and runs a query. On first read it looks fine and it passes the one test the AI generated. But walking through my checklist surfaces four distinct problems in under ten minutes:

  • Line 12 — SQL injection: The query is built with template-string concatenation of userId. A request with 1 OR 1=1 returns every order in the database. Severity: critical.
  • Line 8 — missing authorization: Any logged-in user can read any other user's orders by changing the ID. There is no check that the requester owns the account. Severity: critical.
  • Line 19 — no error handling: A database timeout throws an unhandled rejection that crashes the worker. Severity: high.
  • Line 3 — a hallucinated helper: It imports express-async-safe, a package that does not exist on npm. The AI invented it. Severity: build-breaking, and a typosquat risk if someone later registers that name.

Before: 34 lines, "works," ships in 2 minutes.
After review: 2 critical vulnerabilities, 1 crash bug, and 1 fake dependency caught in about 9 minutes. That 9 minutes is the cheapest security work you will ever do. A single data-leak incident of the kind on Line 8 costs, per IBM's 2024 breach report, an average of $4.88 million. The math is not close.

Notice that the fake-package problem on Line 3 is a distinct discipline. Verifying that a dependency is real, maintained, and not malicious is its own skill, and it's worth reading how to verify a package manager's repository isn't serving malware before you trust any AI-suggested install command.

Manual Review vs. Automated Tools vs. AI Review: What to Use When

No single method catches everything. The strongest setup layers them. Here's how the common approaches compare on the criteria that actually matter day to day.

Approach Catches logic bugs Catches security holes Catches fake dependencies Speed Cost
Manual line-by-line review Excellent Good Good Slow Time only
Static analysis / linters Moderate Good Poor Fast Low / free
Dependency scanners None Moderate Excellent Fast Low / free
A second AI as reviewer Moderate Moderate Poor Fast API cost
Runtime testing in staging Good Moderate None Medium Infra cost

My take: use static analysis and dependency scanning as automatic gates in CI, use a second AI to catch obvious oversights (it's a decent first pass, never a final word), and reserve human review for the two things machines are worst at — intent and authorization logic. That's where the expensive bugs hide.

Can you trust AI to review AI?

Partly. A separate model reviewing the first model's output catches surface-level issues surprisingly well, and it costs pennies. But it shares the same blind spots around your specific business rules, and it will confidently approve code that leaks data if the code merely looks conventional. Treat AI review like spellcheck: useful, not a substitute for reading.

Security Red Flags to Hunt For in AI Output

These are the patterns I search for explicitly, in roughly the order they cause real incidents. Keep this list next to your keyboard.

  • String-built queries. Any SQL, LDAP, or shell command assembled by concatenating user input. Demand parameterized queries or prepared statements every time.
  • Missing authorization checks. The code authenticates (who you are) but forgets to authorize (what you're allowed to touch). This is the single most common serious flaw I see.
  • Hardcoded secrets. API keys, tokens, or passwords baked into source. AI does this constantly because its training data is full of examples that did.
  • Over-broad permissions. chmod 777, wildcard

    Cover image: The Torch Graduate circuit board (bottom) by Chris Whytehead, licensed under BY-SA 3.0 via Openverse.

Recent Posts

View all →

Most Popular Software

View all →

Browse by Platform

View all →