Build fails with Cannot find module './utils/superhelper'. You grep the whole project — the file doesn’t exist. Claude Code or Cursor invented an import to a utility it “expected to be there.” This is one of the most common LLM failure modes: based on training data and similar-project naming conventions, the model “completes” a plausible-looking path without ever creating the actual file. The good news: easy to fix. The compiler tells you exactly which line, and there are only two valid fixes — implement it or replace it. This article covers the causes, fix templates, and prevention rules.
Common causes
Ordered by hit rate, highest first.
1. Agent confused its plan with its code
In reasoning it said “I’ll use a formatDate utility.” In code it just wrote import { formatDate } from './utils/formatDate' — it treated the name from its plan as already-implemented code.
// agent wrote
import { formatDate } from '@/utils/formatDate';
// but the project actually uses
import dayjs from 'dayjs';
How to spot it: Inspect the reasoning trace. Did it ever say “create” or “implement”? If there’s an import but no creation action, this is it.
2. Defaulted to a utility it “expects” to exist
LLMs have seen src/utils/cn.ts, src/lib/utils.ts, src/helpers/format.ts in so many codebases that they assume yours has them too. TypeScript templates and Next.js / shadcn ship lib/utils.ts by default — but maybe you didn’t use shadcn.
How to spot it: Search for stock template paths like src/lib/utils, src/utils/cn, @/lib/db. If you never created them, that’s the bug.
3. Package name from training data
Wrote import { useDebounce } from 'react-use' but you installed usehooks-ts, not react-use. Error: Cannot find module 'react-use'. Technically package hallucination, not file hallucination, but the root cause is identical.
How to spot it: Check package.json; npm list <package> returns nothing — package hallucination.
4. Agent took the wrong workspace path in a monorepo
packages/ui/src/Button.tsx exists, but agent (working in packages/app) wrote import { Button } from '../ui/Button' — math is wrong. The file exists but the relative path doesn’t resolve.
How to spot it: Path in the error is relative and looks suspicious (../../../ui/); check tsconfig paths and actual directory depth.
5. Casing mismatch (works on macOS, fails in CI)
import './Button' but the file is button.tsx. macOS resolves it; Linux build fails. Not strictly hallucination but the symptom is identical.
How to spot it: git ls-files | grep -i button shows the actual on-disk casing.
6. Agent imported a file it planned to create but forgot
In the plan: “I’ll create src/api/posts.ts.” In the code: only the import, never the creation — context window cut off mid-plan or a step got skipped.
How to spot it: Grep the agent’s Write tool calls for this run; if the missing file isn’t in the list, it was never written.
Shortest path to fix
Ordered by ROI. Most cases fix in under 5 minutes.
Step 1: List every hallucinated import with tsc --noEmit
npx tsc --noEmit 2>&1 | grep -E "TS2307|TS2305|Cannot find"
You’ll see something like:
src/components/Form.tsx:5:23 - error TS2307: Cannot find module '@/utils/superhelper'
src/pages/posts.tsx:8:30 - error TS2307: Cannot find module '@/lib/db'
src/hooks/useAuth.ts:3:15 - error TS2305: Module '@/utils' has no exported member 'verifyToken'
One row, one fix.
Step 2: Decide whether the utility should exist
Open the failing file, look at how the import is used:
import { superhelper } from '@/utils/superhelper';
// ...
const result = superhelper(data, { format: 'json' });
Ask yourself two questions:
- Does the project already have an equivalent? (e.g.
lodash,dayjs, a helper you wrote earlier) - If not, is it worth a new file?
| Situation | Fix |
|---|---|
| Equivalent already exists | Change the import, don’t create a file |
| Tiny feature (< 20 lines) | Inline at the call site |
| Genuinely reusable utility | Actually create it |
| Package hallucination | npm install the real package, or swap to an installed equivalent |
Step 3: Grep to find an existing equivalent
Verify before creating:
# By function name
grep -rn "formatDate\|format_date\|dateFormat" src/
# By signature
grep -rn "export function.*Date.*string" src/
# Look for related installed packages
grep -E "(date|format|debounce|throttle)" package.json
If something’s there, swap the hallucinated import for it.
Step 4: Hand the list back to the agent with a precise prompt
Don’t fix every import by hand — feed the list back:
Build is broken. These imports reference non-existent files:
[paste tsc --noEmit output]
Fix rules (strict):
1. Do not create new files unless there is truly no equivalent
2. Before fixing each import, grep the project to check for an existing implementation
3. If a missing npm package, tell me the name — I decide whether to install or swap
4. After fixing, `tsc --noEmit` must be fully green
5. Do not change tsconfig paths
Step 5: For genuinely new files, require a proposal first
If a utility really needs to be created:
You want to create src/utils/X.ts. First output:
1. Full file content (with types)
2. Every call site that will use it
3. Why not use existing lodash / dayjs / native APIs
Wait for my approval before creating it.
This forces a human review and prevents the agent from sprinkling one-call-site “helpers” everywhere.
Prevention
- In CLAUDE.md / AGENTS.md /
.cursorruleswrite: “Before importing, you mustgreporfindto confirm the target exists. Never invent a path” - Add
tsc --noEmitto the agent’s “done” criterion — declaring done requires a clean type check - Pre-commit hook runs
tsc --noEmit; TS2307 / TS2305 blocks the commit - Drop a
docs/utils.mdat the project root listing common helpers and their real paths — feed it to the agent as context - Verify the agent has file-search tools available and uses them — many agents don’t search the file tree proactively by default
- Keep
npm installin its own commit so you can see exactly what was added in any week - In monorepos, use tsconfig
pathsaliases instead of relative paths — hallucination rate drops noticeably
Related
- AI code broke build
- Build passes locally but fails in CI
- Cursor missed project context
- AI pre-commit review workflow
- Claude Code SEO audit
- AI dependency upgrade workflow
Tags: #AI coding #Debug #Troubleshooting