Smells of AI-Generated Code.
Recurring problems in code written by AI coding assistants — how to recognize each one, why models produce it, how to fix it, and the rules that detect it.
An AI assistant wraps code in extra functions, classes, or interfaces that add a layer of indirection without hiding any complexity or enabling reuse — abstractions that merely forward to a single call site.
When writing new code, AI assistants tend to paste or re-derive a slightly tweaked copy of logic that already exists instead of calling or extracting a shared function, so duplicated code grows with every feature.
AI assistants rarely restructure existing code: they bolt new branches, flag parameters and wrapper layers onto what is already there, so functions and conditionals keep growing while refactoring — the rework that keeps a codebase healthy — quietly disappears.
The model hand-writes bespoke code for something a standard library, an existing dependency, or a helper already in the repo already does — adding duplicated, less-tested logic instead of calling what is already there.
AI-generated code that calls functions, methods, parameters, config keys, or packages that look plausible but do not exist in the actual library version you depend on.
AI assistants tend to generate code that handles only the successful, well-formed case — skipping input validation, error handling, null/empty checks, and edge cases — so the code works in the demo and breaks in production.
AI assistants emit functional code that silently omits the security controls a human would add by habit — input validation, authorization, output encoding, secrets handling — because "it compiles and returns 200" looks like done.
Comments that are artifacts of the generation conversation — restated prompts, step-by-step narration, chat asides, and placeholder elisions like `// ... rest of the code here` — committed into source instead of real documentation.
AI assistants pad simple logic with comments that restate each line, step-by-step narration, defensive null ladders, and long-hand expressions where an idiom or an existing helper would do — inflating line count without adding behavior.
An AI assistant names new code with generic placeholders or a fresh convention that ignores the repository's existing identifiers and domain vocabulary, eroding readability and spawning duplicate, mis-described concepts.
AI-generated code that quietly ignores a repo's established conventions — reinventing helpers, picking the wrong library, and using off-house naming and error-handling — so the codebase drifts toward generic, internet-average style.
AI assistants confidently emit APIs, libraries, and idioms that were current years ago but are now deprecated, removed, or superseded, because their parametric knowledge is frozen at a training cutoff and the old pattern is still the statistically most common one in their corpus.
AI assistants hedge against failures that can't happen, wrapping already-safe code in redundant null checks, dead guard clauses, and catch-all try/except blocks that add complexity without adding safety.
AI assistants bake environment-specific values — URLs, ports, paths, timeouts, keys, and magic numbers — directly into logic instead of reading them from config or environment, because a literal is the most probable next token and the model lacks awareness of your existing config layer.