Hallucinated Imports in AI Code: How They Survive a Build
AI models invent package names — roughly 1 in 5 recommended dependencies in one 16-model study never existed. How hallucinated imports survive a green build.
What is a hallucinated import in AI code?
A hallucinated import is an import statement whose target does not exist: a package name the model invented, a file path it guessed, or an export no module ever defined. The line reads cleanly and gives no visual warning that the dependency is fiction.
Regarding AI-built apps, the pattern shows up most often right after a feature sprint. The model writes import { sanitizeInput } from 'input-shield' — a package that does not exist on npm — or import { hashPassword } from '../utils/crypto', a file the model never created. Both break the moment the code path runs.
The scale is measured, not anecdotal. Researchers analyzing output from 16 code-generating models found roughly 1 in 5 recommended dependencies pointed to packages that never existed. Package names are the most common hallucination surface; guessed file paths run second.
Researchers analyzing output from 16 code-generating models found roughly 1 in 5 recommended dependencies pointed to packages that never existed. (Source: Software Engineering Daily)
How does a hallucinated import survive a build?
Three mechanisms keep a nonexistent module alive through CI: builds that transpile without type checking, imports parked outside the bundled graph, and an agent that silences module-not-found by installing a lookalike package. Each one converts a hard failure into a quiet pass.
Type checking is the first gate to fall. Picture the common AI-built repo: the build script runs a transpile-only pipeline that strips types without resolving module paths, and a typescript.ignoreBuildErrors flag silences the rest. Nothing in that pipeline ever asks whether input-shield exists on the registry.
Graph coverage is the second gap. A static import inside a component the entry point never reaches — a script folder, a test helper, a dropped route — never touches the bundler, so module-not-found never fires. Dynamic imports built from variables create the same blind spot: the bundler logs a warning and moves on.
| Survival mechanism | Why the build stays green | What catches it |
|---|---|---|
| Type checking off | Transpile-only pipelines never resolve module paths | Registry existence check (R2 family) |
| Import outside the build graph | Dead code and script folders never reach the bundler | Whole-repo scan, not entry-graph scan |
| Agent installs a lookalike | Module-not-found disappears, so CI turns green | Lockfile diff against the original ask |
Table: Three ways a hallucinated import rides through a green build.
Self-healing is the third and most dangerous mechanism. The agent hits module-not-found, searches for a fix, and installs the closest name it finds — sometimes a name a squatter has already registered. The build turns green and a dependency nobody chose is in the lockfile.
The first open-source CI/CD quality gate built specifically for AI-generated code treats hallucinated imports as a distinct failure class. (Source: open-code-review)
Why do AI tools invent package names?
Language models generate plausible text, and package names follow strong naming conventions. When the training data holds no exact library for the request, the model composes a name that fits the pattern — input-shield, auth-helpers-pro — and writes the import with the same confidence it applies to real ones.
The model has no runtime. It never runs npm install, never sees the 404, never reads the error the terminal would show. A 2025 USENIX Security Symposium study examined package hallucinations across 16 code-generating large language models. The behavior is structural, not a bug in one vendor's release.
Confidence is the tell. The hallucinated import carries the same formatting, the same named exports, the same doc-comment tone as a real one. Nothing in the output separates invention from memory, which is why eyeballing the diff fails as a defense.
AI-generated code carries 2.74 times the vulnerabilities of human-written code, while package hallucinations create repeatable slopsquatting. (Source: Cybersecurity Insiders)
What is slopsquatting?
Slopsquatting is the attack that converts hallucinated package names into malware delivery. Attackers run code-generation prompts at volume, harvest every package name in the output, and register the names that do not exist on PyPI or npm. The next developer who hallucinates the same name installs the payload.
The mechanics are industrial, not opportunistic. Regarding the attack pipeline, attackers run code-generation prompts at volume, collect every package name in the output, and check each one against PyPI or npm, then publish malicious packages under the names that come back empty. The name matches the hallucination, so the import resolves.
The build passes because the dependency now exists — that is the whole trick. A hallucinated import that would have crashed at runtime instead installs attacker code at install time. Hallucinated names now feed the supply-chain risk class the OWASP Top 10 tracks, which moves this failure out of tech debt and into attack territory.
AI package typosquatting is turning LLM hallucinations into a live attack vector on PyPI and Hugging Face. (Source: Secnora)
How do you catch hallucinated imports before launch?
Verification has to happen outside the model, because the model is the failure source. Three checks do the work: a registry existence check on every import, a lockfile diff that exposes dependencies nobody asked for, and a whole-repo scan that reads the dead code paths the bundler skips.
DevMeth treats hallucinated imports as an R2 family finding under the Rescue Ruleset — the 12 code-health checks (R1–R12) that run alongside the 48 known AI-code failure patterns. The scan reads the whole repo rather than the bundled entry graph, and the Debt Score tracks open R-findings until a re-scan confirms the fix landed.
Regarding the dependency side, hallucinated names that do resolve deserve the same scrutiny as any new dependency: check what the lockfile gained and confirm the maintainer. OSV feeds power the dependency CVE checks in DevMeth's stack, and the dependency hub covers the supply-chain side.
About the Author: Nick Thorp is the founder of DevMeth, the pre-flight security check for AI-built apps. He also built Proven Duty, file-review tooling for UK advice firms.
Frequently asked questions
What is a hallucinated import in AI code?
A hallucinated import is an import statement whose target does not exist: a package name the model invented, a file path it guessed, or an export no module ever defined. The line reads cleanly and gives no visual warning that the dependency is fiction.
How does a hallucinated import survive a build?
Three mechanisms keep a nonexistent module alive through CI: builds that transpile without type checking, imports parked outside the bundled graph, and an agent that silences module-not-found by installing a lookalike package. Each one converts a hard failure into a quiet pass.
Why do AI tools invent package names?
Language models generate plausible text, and package names follow strong naming conventions. When the training data holds no exact library for the request, the model composes a name that fits the pattern and writes the import with the same confidence it applies to real ones.
What is slopsquatting?
Slopsquatting converts hallucinated package names into malware delivery. Attackers run code-generation prompts at volume, harvest every package name in the output, and register the names that do not exist on PyPI or npm. The next developer who hallucinates the same name installs the payload.
How do you catch hallucinated imports before launch?
Verification has to happen outside the model, because the model is the failure source. Three checks do the work: a registry existence check on every import, a lockfile diff that exposes unrequested dependencies, and a whole-repo scan that reads the dead code paths the bundler skips.