Developer reviewing source code and test results beside an AI coding assistant

Editorial illustration; it does not show a real codebase or AI tool.

Published on October 20, 2026.

AI coding assistants can turn a blank file into a useful first draft in seconds. They can explain an unfamiliar function, suggest a test, translate code between languages and help you get past a tedious piece of syntax. That speed is valuable, but it changes the job of the developer rather than removing it.

The difficult question is no longer only “Can this code be written?” It is “How do I know this code is correct, safe and appropriate for this system?” A plausible-looking answer can still misunderstand the requirement, mishandle an edge case, expose data or introduce a dependency that nobody has time to maintain.

Quick Answer

Before shipping AI-generated code, review it in this order:

  1. Restate what the code is supposed to do, including what it must not do.
  2. Read the complete change, not just the lines suggested by the tool.
  3. Check inputs, outputs, error paths and boundary conditions.
  4. Look for security problems such as injection, weak access control and secret leakage.
  5. Run focused tests, then run the wider project checks.
  6. Inspect every new dependency and permission.
  7. Compare the change with the project’s existing conventions.
  8. Ask another person or another tool to challenge the assumptions.
  9. Record what was generated and what you verified.
  10. Keep the change small enough to understand and remove.

An AI assistant can help with each step, but it cannot take responsibility for the result. The person merging the code still needs enough understanding to explain why it belongs in production.

1. Start with the requirement, not the generated diff

The first review mistake is to read the proposed code before deciding what success means. Code is persuasive because it is concrete. A function with a tidy name and comments can make an incomplete requirement feel settled.

Write a short contract in plain language. For a password-reset endpoint, that might be: “A user with a valid, unexpired token can set a new password; the response must not reveal whether an email address exists; the token can be used only once.” The contract gives you something to test against.

Also write down non-goals. Perhaps the endpoint does not send email, change a user’s session or support administrator impersonation. Explicit boundaries make it easier to spot when generated code quietly grows beyond the request.

2. Read the whole change in context

Do not approve a snippet just because it works in isolation. Inspect the caller, the data model, the configuration, the error handler and the code that consumes the result. An AI assistant usually sees a limited window of the repository and may not know about a convention in another package or a constraint in a deployment environment.

Check whether the code duplicates an existing helper. Search for similar behaviour before accepting a new utility, validation rule or database query. Two slightly different implementations of the same rule are an invitation for them to drift apart.

A useful review question is: “What assumptions does this code make about the rest of the application?” Write those assumptions down. Then verify them in the source, documentation or tests rather than treating the generated explanation as evidence.

3. Test the happy path and the awkward paths

Generated code often demonstrates the normal example first. Your tests should spend time on the examples that are easy to forget:

  • empty, missing, malformed and unexpectedly large inputs;
  • duplicate requests and repeated submissions;
  • expired, cancelled or already-used tokens;
  • a user who is authenticated but not authorised;
  • a network, database or third-party service timeout;
  • partial failure after one side effect has already happened;
  • different time zones, locales, encodings and daylight-saving rules where relevant;
  • lists with zero items, one item and many items.

For each case, decide what the caller should see and what should be logged. A test that merely checks for a 200 response may miss a response containing the wrong user’s data or a success message produced after a failed write.

Ask the AI tool to generate adversarial cases, but do not let its list become your complete test plan. The important cases come from the business and the system, not from how imaginative the prompt sounds.

4. Treat security review as a separate pass

Correctness and security overlap, but they are not the same review. Read the code specifically for trust boundaries: where does data from a browser, webhook, file, URL or external API enter the program? What does it control? Which account or process runs the operation?

Look for familiar failure modes:

  • SQL, shell, template or HTML injection caused by building commands from untrusted strings;
  • missing authorisation checks because the code verifies identity but not ownership;
  • sensitive values written to logs, error messages, URLs or client-side storage;
  • unsafe file paths, archive extraction or redirects;
  • permissive CORS, cookie, token or encryption settings;
  • secrets copied into source code or test fixtures;
  • regular expressions or loops that can consume excessive CPU or memory;
  • dependency versions that are unpinned, abandoned or broader than necessary.

Do not assume that a comment saying “sanitise input” proves that input is safe. Follow the value from its source to its dangerous use and identify the actual validation or parameterisation step. OWASP’s secure coding guidance and its Top 10 project are useful review prompts, but the project’s framework and deployment context still matter.

5. Check the libraries and permissions

An apparently small feature can add a large dependency tree. Inspect the package manifest and lockfile, not only the import statement. Ask why the dependency is needed, who maintains it, what license applies and whether an existing project library already provides the same function.

The same principle applies to permissions. A script that only formats an uploaded image should not need broad access to the user’s home directory. A CI job that runs tests should not automatically receive production credentials. AI-generated configuration often copies a working example with permissions that are convenient for a demo but excessive for a real service.

Use the narrowest permission that allows the task, and make the permission visible in the review. If you cannot explain why a new capability is required, pause before merging it.

6. Compare the result with project conventions

A technically valid solution can still be a poor fit. Check naming, error types, logging style, transaction boundaries, configuration patterns and test structure. Consistency is not merely cosmetic: it reduces the amount of code future maintainers must understand.

Pay special attention when generated code introduces a new abstraction. A generic “manager”, “helper” or “service” can hide a simple operation behind extra indirection. Conversely, a long function may be forcing business rules, persistence and presentation into one place. Prefer the smallest shape that matches the repository’s existing design.

If the code disagrees with a documented project rule, the developer should decide whether the rule is outdated and change it deliberately. The AI assistant should not silently create a new exception.

7. Use tests as evidence, not as a permission slip

Passing tests are encouraging, but they prove only what those tests cover in that environment. A generated test can repeat the same mistaken assumption as the generated implementation. It may also mock away the database, authentication service or network behaviour that creates the real risk.

Read the test itself. Does it assert the important result, or only that a function was called? Does it fail when the implementation is wrong? Add a regression test for the bug or requirement that motivated the change, and run the project’s formatter, linter, type checker and integration tests when they exist.

For security-sensitive changes, test the negative result too: an unauthorised request is rejected, an invalid signature is not accepted, and a secret is absent from the response. Test failures are information about the contract, not an inconvenience to silence.

8. Ask questions that expose uncertainty

An AI assistant is useful during review when you ask it to criticise a specific decision. Try prompts such as:

“List the assumptions this function makes about authentication and identify where each is enforced.”

“Give three inputs that could cause this parser to return an unsafe result.”

“What happens if the database write succeeds but the following network call fails?”

“Which parts of this answer depend on a library version or framework setting?”

Treat the output as a set of questions, not an approval. Have a human reviewer inspect the parts involving money, permissions, personal data, production changes or irreversible actions. A second pair of eyes is especially valuable when the author is also the person who wrote the prompt and selected the generated answer.

Why this matters

The cost of AI-generated code is not limited to bugs in the first release. Unclear provenance can make a later incident harder to investigate. A team may not know which requirement was considered, whether a code path was manually checked or why a dependency was added. Fast generation can therefore create slow maintenance.

That does not mean teams should avoid AI assistance. It means the quality process must keep pace with the output. Small changes, readable diffs, meaningful tests and clear ownership turn generated suggestions into maintainable software.

Common mistakes to avoid

The most common mistake is equating fluency with correctness. A confident explanation is not a test result. Another is asking the assistant to “make it production-ready” without supplying the requirements, threat model, supported versions or failure policy that production actually requires.

Avoid pasting secrets, private customer data or proprietary source into a tool unless your organisation has approved that use and you understand the tool’s data handling. Keep prompts and generated outputs out of logs when they contain sensitive material. Finally, do not merge a large generated rewrite just because reviewing it line by line feels difficult. Split it into smaller changes that can be tested and reverted.

My Take

AI coding tools are most valuable when they reduce typing and widen the set of questions a developer can ask. They are least valuable when they encourage us to skip understanding. I would rather merge a small, clearly reviewed AI-assisted change than a brilliant-looking block that nobody on the team can confidently explain.

My practical rule is simple: if you cannot describe the failure modes and the tests that cover them, the code is not ready, regardless of who wrote it.

Bottom Line

Review AI-generated code like code from a fast junior contributor: appreciate the useful draft, verify every important assumption and take responsibility for the final decision. Start with the requirement, inspect the full context, test awkward cases, perform a dedicated security pass and keep dependencies and permissions narrow.

The assistant can help you produce code faster. A disciplined review is what makes that code safe to keep.

Sources