How to Review AI-Generated Code Before You Merge: A Practical Checklist

AI coding assistants can now write whole functions, open pull requests, and even fix their own failing tests. That is a real productivity boost, but it also changes your job. You write less of the code yourself, so more of your value comes from reading it carefully before it reaches your users. Code that looks clean and passes a quick glance can still hide bugs, security holes, and design choices you would never have made yourself.

This guide gives you a practical checklist for reviewing AI-generated code. It works whether you are a student building a capstone project, a freelancer shipping client work, or a developer on a team that uses Copilot, Claude Code, Codex, or any other assistant.

Why AI-Generated Code Needs a Different Kind of Review

When a teammate writes code, you can usually guess their intent and ask them about it. AI output is different in a few important ways:

  • It sounds confident even when it is wrong. The code is neatly formatted and well named, which makes mistakes easier to miss.
  • It fills gaps with guesses. If your prompt did not mention an edge case, the assistant picks a behavior for you, and it may not be the one you want.
  • It can invent things. Assistants sometimes call functions, options, or packages that do not exist, or that exist in a different version of a library.
  • It produces a lot of code fast. A large diff is harder to review than a small one, and it is tempting to skim.

None of this means you should stop using AI tools. It means you should review their output as if it came from a talented new hire who has never seen your project before.

Step 1: Understand the Change Before You Read the Code

Start by restating the task in one or two sentences. What should this change do, and what should it not touch? Then look at the list of changed files. If you asked for a fix in one controller and the diff edits your database config, your build script, and three unrelated tests, stop and ask why.

Scope creep is one of the most common problems with agent-generated pull requests. Ask the assistant to split the work into smaller changes, or revert the parts you did not ask for. Small, focused diffs are easier to review and safer to merge.

Step 2: Run It, Do Not Just Read It

Never merge code you have not run. Pull the branch, install dependencies, and exercise the feature the way a user would. Then run the full test suite, not just the tests the assistant added.

Also check that the new tests actually test something. AI-written tests sometimes only confirm that the code runs without crashing, or they assert whatever the current output happens to be. A good test should fail if you break the feature on purpose. Try it: change one line of the new code, run the tests, and make sure at least one of them turns red.

Step 3: Hunt for Subtle Logic Bugs

Logic bugs are where reviews earn their keep. Here is a classic example in Python that looks perfectly reasonable at first glance:

  1. def add_tag(tag, tags=[]):
  2.     tags.append(tag)
  3.     return tags
  4.  
  5. print(add_tag("python"))
  6. print(add_tag("php"))

You might expect the second call to return a list with just "php". Instead, the output is:

['python']
['python', 'php']

The default list is created once, when the function is defined, and then shared between calls. The fix is to use None as the default and create a new list inside the function. Pair the fix with a test that would have caught the bug:

  1. def add_tag(tag, tags=None):
  2.     if tags is None:
  3.         tags = []
  4.     tags.append(tag)
  5.     return tags
  6.  
  7. def test_add_tag_starts_fresh_each_call():
  8.     assert add_tag("python") == ["python"]
  9.     assert add_tag("php") == ["php"]
  10.  
  11. test_add_tag_starts_fresh_each_call()
  12. print("All tests passed")

Running this version prints All tests passed. The lesson is not about this one Python quirk. It is that AI tools reproduce patterns they have seen many times, including buggy ones. While reviewing, look closely at:

  • Off-by-one errors in loops, slices, and pagination.
  • Empty inputs, null or None values, and very large inputs.
  • Time zones, date boundaries, and currency rounding.
  • Error handling that silently swallows exceptions with an empty catch or except block.
  • Shared state, caching, and anything that runs concurrently.

Step 4: Check Security Like an Attacker Would

Security problems are the most expensive things to miss. For web projects, which make up much of what we share on SourceCodester, check these points on every AI-written change:

  • SQL queries: Make sure user input goes through prepared statements or your framework's query builder, never through string concatenation.
  • Output escaping: Anything a user can type should be escaped before it is shown on a page, to prevent cross-site scripting.
  • Authentication and authorization: Confirm that each new route or API endpoint checks who the user is and whether they are allowed to do this action.
  • Secrets: Look for API keys, passwords, or tokens hard-coded in the diff. They belong in environment variables or a secrets manager.
  • File uploads and paths: Validate file types and sizes, and never build file paths directly from user input.

If your project has a linter or a static analysis tool, run it on every AI-generated change. These tools are cheap, fast, and catch many of the issues above automatically.

Step 5: Verify Every Dependency and API Call

When the assistant adds a new package, look it up on the official registry (such as PyPI, npm, or Packagist) before you install it. Check that it is the package you think it is, that it is actively maintained, and that the name is not a lookalike of a popular library. Typo-style package names are a known way attackers sneak malicious code into projects.

For unfamiliar functions or options, open the official documentation for the version you actually use. If you cannot find the method the assistant called, it may have been made up or taken from a different version.

Step 6: Judge Readability and Fit

Working code is not automatically good code. Ask yourself whether you could explain this change to a classmate or teammate. Does it follow your project's naming conventions, folder structure, and error-handling style? Did the assistant add a new helper function when one already exists elsewhere in the codebase? Duplicated logic is a maintenance problem waiting to happen.

If a section is hard to understand, ask the assistant to explain it, then decide whether to simplify it. Code you do not understand is code you cannot safely maintain.

A Quick Checklist You Can Copy

  • Does the change do only what was asked?
  • Did I run the feature and the full test suite myself?
  • Do the new tests fail when the code is broken on purpose?
  • Have I checked edge cases, empty inputs, and error handling?
  • Is all user input validated, escaped, and passed safely to the database?
  • Are there any hard-coded secrets?
  • Is every new dependency real, maintained, and necessary?
  • Can I explain every line to someone else?

Conclusion

AI assistants are excellent at producing a first draft, and they are getting better every month. But the responsibility for what ships is still yours. A careful, repeatable review process turns a fast assistant into a reliable one. Keep your changes small, run everything, think like an attacker, and never merge code you cannot explain. Your future self, and your users, will thank you.