The working discipline for an AI coding assistant is simple to state and hard to keep: treat every suggestion as a claim, not a fact, and verify it at the cheapest point possible before it costs you anything. That means checking that an imported package exists before running an install, checking that a called function is real before trusting the diff, and reading the failure paths of a change before the happy path, because the assistant already got the happy path right. None of this requires distrusting the tool outright. It requires refusing to extend it credit it has not earned on this specific line of code.
That single habit is the difference between an AI coding assistant that makes a working developer faster and one that quietly fills a codebase with plausible mistakes. The rest of this guide covers where the failures actually cluster, a technique for catching them before they reach a pull request, and where to go for the specific checks this pillar hands off to.
Why trust in AI-written code is falling as adoption climbs
The pattern showing up across developer surveys through 2026 is not the one the marketing decks describe. Adoption of AI coding assistants like GitHub Copilot, Cursor and Claude Code keeps climbing, but self-reported trust in what they produce has been falling, not rising, as developers spend more hours actually reviewing the output. That is not a contradiction. It is what happens when a tool goes from a novelty to a daily habit: the honeymoon period where every suggestion feels impressive gives way to the working period, where every suggestion gets checked against a codebase that has actual consequences.
This is worth stating plainly because it reframes the whole subject. The goal of working with an AI coding assistant is not to build trust in the tool as a general proposition. It is to build a set of cheap, specific checks that make the question of “do I trust this” irrelevant, because you verify instead of trusting.
The three places an assistant actually fails
Failures do not spread evenly across a codebase. They cluster in three predictable places, and knowing the shape of each one is most of the battle.
Invented packages. An assistant asked to solve a problem will sometimes recommend installing a package that does not exist. This has a name in the security industry now, slopsquatting, because it has become an actual attack surface: someone registers the invented package name on npm or PyPI and ships malware inside it. A large academic study found close to a fifth of packages recommended by code-generating models across a large test corpus simply did not exist, and that when the same prompt was run repeatedly, a substantial share of the invented names reappeared every time, which means this is not random noise, it is a predictable failure pattern. The full mechanics and the specific check for this belong to a dedicated piece, linked below.
Invented functions and API surfaces. The same failure shows up one level down: not a package that doesn’t exist, but a method on a real package that was never added, or a function signature that looks plausible but was never shipped. This is harder to catch than a missing package because the import line looks completely normal. It only breaks at call time, or worse, it silently returns the wrong thing if a similarly named real method exists nearby.
Plausible-but-wrong logic that passes tests anyway. The hardest category, because nothing crashes. The code runs, the tests the assistant wrote alongside it pass, and the behavior is still wrong, usually because the assistant wrote tests that describe what the code does rather than what the code was supposed to do. This category rewards actually reading the logic, not just running it.
The adversarial pass: asking the assistant to break its own work
One technique shows up repeatedly in the testing-strategy discussion around AI-written code, and it is worth adopting as a habit rather than an occasional trick: after the assistant produces a solution, ask it (in a fresh prompt, not a follow-up in the same thread) to find problems with that solution instead of asking it to confirm the solution is correct. The framing matters more than it sounds like it should. A prompt that says “write this” optimizes the model toward something plausible and complete. A prompt that says “find every way this breaks” optimizes it toward failure modes, edge cases, and the assumptions the first pass quietly made. The same model, asked the second way, will often surface exactly the boundary condition or missing null check that the first pass glossed over.
This does not replace human review. It is a cheap first pass that catches a meaningful share of the plausible-but-wrong category before a person has to read a line of the diff.
What to check before you even open the diff
Three things are worth confirming before you start reading line by line, because they change how much scrutiny the rest of the diff needs.
How much of the codebase did the assistant actually see? A suggestion generated from a narrow slice of context (one open file, no view of a related module three directories over) is guessing about conventions it cannot see. The narrower the context, the more the output needs treating as a first draft rather than a finished change.
Did anything from a .env file or a secrets manager enter the conversation? Large context windows and “give it the whole repo” workflows make it easy for an API key or a credential to end up inside a prompt without anyone deciding that should happen. Checking this before reviewing logic is not paranoia; it is the cheapest possible check, and the cost of skipping it once is disproportionate to the ten seconds it takes.
Is this a narrow, single-purpose change, or did the assistant wander? An assistant asked to fix one thing will sometimes “helpfully” reformat a file, rename a variable, or touch a config it was never asked to touch. That scope creep is often where the actual risk hides, because reviewers stop reading carefully once a diff looks large and unfocused.
Deep Dives: the practices this pillar hands off to
Each of the failure modes above has its own dedicated, deeper piece. This pillar is the map; these are the routes.
- How to Spot a Hallucinated Package Before You Run npm install the specific, mechanical check for the invented-package failure, including what slopsquatting actually looks like in a terminal.
- The AI Invented a Function That Does Not Exist: How to Check an API Surface Fast a fast way to confirm a called method or function is genuinely part of the library it claims to belong to.
- Reviewing an AI Pull Request That Touches 40 Files what changes about code review once the diff is too large to read start to finish in one sitting.
- Ten Checks Before You Merge AI-Written Code the short, ordered list to run through before the merge button, regardless of how the code was written.
FAQ
Is it safe to let an AI coding assistant write production code unsupervised?
Not without the same review discipline you would apply to a change from a junior contributor working from an incomplete spec: read the diff, run the tests, and specifically check the failure paths, not just the success path.
Does using an AI coding assistant make code review slower or faster overall?
Individual suggestions come faster, but reviewing the output responsibly takes real time, particularly on larger changes. The net effect depends entirely on whether that review time is actually spent, or skipped because the diff “looks fine.”
Should I trust an assistant more once it has been right several times in a row?
No. Treat every suggestion on its own merits. A model that got the last five suggestions right has not changed the odds on the sixth; it has just been lucky or working in familiar territory so far.
What is the single highest-value check if I only have time for one?
Confirm every new import or dependency actually exists and is the package you think it is, before anything else. It is the cheapest check and it guards against the failure mode with the worst downside a malicious package landing in your dependency tree.
Do GitHub Copilot, Cursor and Claude Code fail in the same ways?
The three failure categories above (invented packages, invented functions, and plausible-but-wrong logic) show up across every current AI coding assistant, because they come from how these models generate text, not from a specific product’s implementation. The discipline in this guide applies regardless of which one is open in your editor.
