Why AI Writes Code That Does Not Work
Five distinct reasons AI generated code fails, how to tell them apart from the symptom, and the specific fix each one needs.
AI writes code that does not work for five distinct reasons, and they need different fixes. It cannot see enough of your project, it is reproducing patterns that have since changed, it is optimising for plausible rather than correct, it is faithfully building an ambiguous request, or it never ran the code it handed you. Treating all five as one problem called "the AI is bad at this" is why people stay stuck.
Here is how to tell them apart from the symptom, and what each one actually needs.
1. It cannot see the rest of your project
The symptom is code that is fine in isolation and wrong for your codebase. It calls a helper that does not exist, re-implements something you already have under a different name, or assumes a data shape that stopped being true three files ago.
This is not a reasoning failure. It is a visibility failure. The model wrote a sensible function for the project it was shown, which was a fragment of the project you have.
The fix is to change what it can see rather than how you ask. Send the files it needs to be consistent with, especially the ones defining your data. Where the amount involved is the constraint, understanding how the context window works tells you what to send and what to leave out.
2. It is reproducing patterns that have moved on
The symptom is code that would have been correct at some point in the past. A function that was renamed, an argument that was removed, a library whose recommended usage changed, an authentication flow that has since been deprecated.
This one is dangerous because the output looks authoritative and often nearly compiles. The failure is confident and specific, which is exactly the profile of something you do not think to double check.
The fix is to give the model current material rather than argue with it. Paste the relevant page of the current documentation into the conversation, or state the version you are on. Telling it that it is wrong without supplying what is right usually produces a second confident guess.
This same risk compounds when the model version itself disappears. Code and habits built around a specific model quietly break the same way code assuming a renamed function does, which is exactly what happens on Claude Opus 4.1's retirement.
3. It is optimising for plausible, not for correct
The symptom is a function that is shaped exactly right and wrong in the middle. Correct signature, sensible variable names, clean structure, and an off by one error or an inverted condition buried in it.
These models generate text that fits the pattern of correct code. Most of the time text that fits the pattern of correct code is correct code, which is why this works at all. When it is not, the failure is invisible to a skim, because everything that makes code look right is present.
The fix is a testing habit, not a prompting one. Run it against a case you already know the answer to. Boundary cases catch most of these: zero items, one item, the last day of the month, a duplicate submission.
4. It is faithfully building an ambiguous request
The symptom is code that does what you asked for and not what you meant. You asked for a delete button and got one that deletes the record permanently, when you meant it should be recoverable. Nothing failed. A gap in your request got resolved into a decision.
This is by far the most common cause and the least often diagnosed, because the code works. It just works in a way you did not intend, and you find out later.
The fix is to state the rules and the check alongside the request. Our guide to writing prompts for AI app builders has the skeleton and worked rewrites.
5. It never ran what it gave you
The symptom is code that does not survive first contact with execution. Missing import, unhandled null, a dependency that was never installed.
Whether this can happen at all depends entirely on which kind of tool you are using. A chat window that produces text has no way to check its own output. A tool that edits files and runs the project catches this class of error before you see it, because running the code and reacting to the result is the defining behaviour of an AI coding agent.
If you are hitting this repeatedly, the fix is a tool change rather than a prompt change. You are asking something that cannot execute code to guarantee code executes.
That covers code that fails before it ships. If something you built this way is already live and it breaks after the fact, the triage is different from a normal debugging session. See what to do when your AI-built app breaks in production for the steps.
Diagnosing from the symptom
What you are seeing | Most likely cause | First thing to try |
|---|---|---|
Calls something that does not exist in your project | Cannot see the project | Send the relevant files, especially your data definitions |
Uses an outdated function or argument | Reproducing stale patterns | Paste the current documentation page |
Looks perfect, wrong result | Plausible over correct | Test a case where you know the answer |
Works, but not how you wanted | Ambiguous request | Restate with the rule and the check |
Crashes immediately on first run | Never executed | Use a tool that runs the code, or run it yourself first |
The pattern underneath all five
Four of the five are information problems rather than intelligence problems. The model did not have your files, did not have current documentation, did not have your unstated rule, or did not have the ability to run anything. Only the third case is a genuine limitation of how these systems generate output, and testing catches it.
That reframing is useful because it points at what you can change. You control what the model can see, what reference material it has, how precisely you specify, and whether the tool can execute. Those four levers cover most of the failures people attribute to the model being unreliable.
If you are early enough that this is all abstract, the fastest way to develop the instinct is to build something small and watch which of the five you hit. A first project takes about 45 minutes. For a larger build, the scoping decisions in our guide to building an app with AI prevent most of the fourth case before it happens.
Understanding why these failures happen is half the fix. The other half is a habit: a five-minute review process that catches the specific places AI-generated code tends to break before it ships.
Once you understand why a bug happened, the next skill is finding it fast in code you did not write yourself. See how to debug AI-generated code for the process.
Frequently asked questions
Does using a better model fix this?
Partly. Stronger models reduce the plausible but wrong category and follow long instructions more reliably. They do not fix code written without sight of your project, and they do not resolve an ambiguous request in your favour.
Why is the AI so confident when it is wrong?
Because confidence is a property of the writing style, not a signal about accuracy. There is no internal check that produces hedging when the output is uncertain, so wrong answers arrive in the same tone as right ones.
Should I ask the AI to check its own work?
It helps for the plausible but wrong category, and it helps far more when the tool can actually run the code and read the error. Self review without execution is another guess, sometimes a better one.
Is it faster to fix AI code or write it myself?
For anything routine, fixing is faster. The exception is when you have gone three or four rounds on the same bug, at which point the conversation has usually accumulated enough noise that a fresh start beats another correction.
The interaction style you use shapes how often you hit this failure mode, compared in AI pair programming vs autocomplete
How did this land?
About the author

Senior Editor, AI & Product
Cecilia leads the Swarmz editorial desk. She has spent a decade turning complex AI and product topics into writing people actually finish, and she owns the blog's quality bar.


