Fix: Hallucinated File Paths
Error Message:
"ENOENT: no such file or directory, open 'src/utils/helpers.ts'" "Cannot write to src/components/Header.tsx (directory does not exist)" "Error: File not found: src/app/api/users/route.ts" Claude edits a file at a path that doesn't exist, or creates a file in a directory that was never part of your project.
What This Error Means
Claude is trying to read, write, or edit a file at a path that doesn't exist on disk. This isn't a permissions issue — the path is simply wrong. The directory may not exist, the file may have a different name, or Claude may be using a path convention from a different project or framework version. The filesystem rejects the operation, and the tool call fails.
Root Cause Analysis
Claude generates file paths based on patterns it's seen in its training data and in the current conversation. When it hasn't recently read your actual project structure, it falls back on conventions: React projects use src/components/, Next.js apps use src/app/, utilities go in src/utils/. These are common but not universal. Your project might use app/components/ (Next.js App Router without a src/ directory), lib/ instead of utils/, or a completely custom structure. Claude doesn't know that unless it's looked.
The problem compounds in long sessions due to context eviction. Early in the conversation, Claude may have read your project structure and navigated correctly. Twenty messages later, that structure read has fallen off the context window. Claude now reconstructs paths from memory — and LLM "memory" in this context means statistical patterns, not a verified filesystem snapshot. It confidently writes to src/components/Button.tsx even though your project puts components in app/components/, because src/components/ is the more common pattern in its training data.
A third trigger is cross-project contamination. If you've worked on multiple projects with Claude in the same session (or if the conversation includes references to another project's structure), Claude can mix conventions. It might use the pages/ directory from a Next.js Pages Router project when working on an App Router project, or reference a server/ directory from an Express app while working on a Next.js API route project.
The final pattern is invented intermediate directories. Claude decides a new helper function belongs in src/utils/auth/helpers.ts, but src/utils/auth/ doesn't exist — only src/utils/ does. Instead of creating the directory first, it tries to write the file directly, and the filesystem rejects it because the parent directory is missing.
Real-World Scenario
You're working on a Next.js 14 project using the App Router. Your structure is app/components/ui/Button.tsx — no src/ directory. After a long debugging session, you ask Claude to "create a new Card component in the components folder." Claude writes to src/components/Card.tsx. The write fails with ENOENT because src/ doesn't exist. Claude then tries components/Card.tsx — also wrong, because your components are under app/components/. After two failures, Claude might give up or create a src/components/ directory that fragments your project structure, leaving components in two different places.
Step-by-Step Fix
Step 1: Stop and make Claude look at the actual structure
Before any file creation or edit, force Claude to read the real directory tree:
"Stop. Run `find . -type f -name '*.tsx' -not -path './node_modules/*' | head -50`
to see the actual file structure. Do not create or edit any file until you've
confirmed the correct path."
Or for a broader view:
# If tree is installed:
tree -L 3 -I 'node_modules|.git' --dirsfirst
# If not:
find . -type d -not -path './node_modules/*' -not -path './.git/*' -not -path './.next/*' | sort
Step 2: Correct the specific path
Once Claude has the real structure, tell it the exact path to use:
"The project does not use a src/ directory. Components live in
app/components/ui/. Create the Card component at
app/components/ui/Card.tsx. Do not create a src/ directory."
Step 3: Create missing directories explicitly
If the target directory genuinely doesn't exist yet (you're adding a new module), have Claude create it first:
mkdir -p app/components/ui
Then create the file. Never assume the directory exists — always mkdir -p first.
Step 4: Provide a structure map at session start
For any non-trivial project, give Claude a reference at the beginning of the session:
"Here's my project structure:
app/
components/
ui/ # reusable UI primitives (Button, Card, Input)
features/ # feature-specific components
api/
users/
route.ts
page.tsx
lib/
utils.ts
auth.ts
There is no src/ directory. Do not create one."
This sets the correct mental model before Claude starts generating paths.
Step 5: Fix already-created wrong paths
If Claude already created files in the wrong location, move them:
# Check what was created:
git status
# Move files to the correct location:
git mv src/components/Card.tsx app/components/ui/Card.tsx
# Remove the incorrectly created directory if it's now empty:
rmdir src/components src 2>/dev/null
# Verify:
find . -name 'Card.tsx' -not -path './node_modules/*'
Common Pitfalls
- Letting Claude create
src/when your project doesn't use it. This fragments your codebase. Always checkgit statusafter Claude creates new files to catch misplaced directories early. - Assuming Claude remembers the structure from earlier in the session. If the session is long, the structure read may have been evicted. Re-read it.
- Using vague instructions like "put it in the components folder." If you have multiple component directories (
app/components/,components/,packages/ui/components/), Claude will guess. Be explicit: "put it inapp/components/ui/". - Not checking after a "successful" file creation. Claude might create the file in the wrong place without erroring — the write succeeds, but the path is wrong. The build then fails with "Module not found" later. Always verify new file paths with
git status. - Cross-project contamination in multi-repo sessions. If you reference another project's structure in conversation, Claude may conflate the two. Keep sessions scoped to one project.
Prevention Checklist
- At the start of every session, run
find . -type f -not -path './node_modules/*' -not -path './.git/*' | head -80and let Claude read the output. - Explicitly state your directory conventions: "No src/ directory. Components go in app/components/. Utils go in lib/."
- When asking Claude to create a new file, specify the full path: "Create app/components/ui/Card.tsx."
- After Claude creates files, run
git statusto verify they landed in the right place. - If your project has an unusual structure, add a
.cowork/structure.txtfile listing key paths and ask Claude to read it at session start. - For monorepos, specify which package you're working in: "We're in packages/web, not packages/api."
- Re-read the project structure after long sessions to counteract context eviction.