[BUG] Native Windows binary fails on every prompt — EEXIST in OAuth token path

Resolved 💬 19 comments Opened Feb 23, 2026 by BlueBit-jpg Closed Apr 12, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

After an extended session or certain operations, every prompt in the native Windows PowerShell binary fails immediately with an EEXIST error. Claude starts and the UI renders normally, but no prompt ever receives a response. The failure is universal for the remainder of the session — restarting the machine does not resolve it. Reinstalling the binary temporarily fixes it, but the issue recurs.

Debug logs show the error originates in the OAuth token check path, milliseconds after startup, before any network request is made.

What Should Happen?

Prompts should be processed normally. The ~/.claude directory already existing is the normal state for any returning user — the mkdir call in the OAuth credential path should handle this gracefully (e.g., fs.mkdirSync(path, { recursive: true })).

Error Messages/Logs

API Error: EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude'

  From debug log (~/.claude/debug/<session-id>.txt):

  [API:auth] OAuth token check starting
  API error (attempt 1/11): EEXIST: file already exists, mkdir
  'C:\Users\<user>\.claude'
  Error in API request: EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude'
  Connection error details: code=EEXIST, message=EEXIST: file already exists, mkdir
  'C:\Users\<user>\.claude'

  Secondary cascading error in the same log:

  SyntaxError: JSON Parse error: Unexpected identifier "API"
      at <parse> (:0)
      at parse (unknown)
      at <anonymous> (B:/~BUN/root/claude.exe:112:1137)

  The error handler appears to attempt JSON-parsing the EEXIST error string, producing
  a second failure.

Steps to Reproduce

Exact trigger is uncertain, but two patterns have been observed:

  1. Leave Claude Code open in PowerShell for an extended period (e.g., overnight)
  2. Return to the session and send any prompt
  3. → API Error: EEXIST: file already exists, mkdir 'C:\Users\<user>\.claude'

Alternate observed trigger:

  1. Open Claude Code in PowerShell
  2. Run /condense during a session
  3. Send any subsequent prompt
  4. → Same error

It is unclear whether /condense is a direct trigger or coincidental. The
extended-session pattern is the more consistent observation, and is consistent with an OAuth access token expiring and the refresh/write path hitting the unguarded mkdir call.

Claude Model

Sonnet (default)

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.49 or 2.1.47. (Claude Code) for both. 2.1.50 technically runs, it just breaks after extended use. To be fair, I hadn't used it extensively until yesterday and today (Feb 21, 22) so the issue might be older.

Claude Code Version

2.1.50 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

  • The ~/.claude directory exists and is fully intact with correct permissions — this is not a corrupted install
  • The bug does not occur in the WSL build of the same version, suggesting it is specific to the Windows native (Bun-compiled) binary
  • The mkdir call in the OAuth token path is the suspected root cause — it does not account for the directory already existing

Possible contributing factor: Claude Code was launched from C:\Users\austi (the user's home directory) as the working directory. This causes the global ~/.claude and the project-level .claude to resolve to the same path (C:\Users\austi\.claude). It is possible the mkdir error is triggered by this path collision — the code may attempt to initialize the project .claude directory without recognizing it is already the global config directory. This could explain why the bug is not reproducible on WSL, where the home directory (/home/austi) differs from the Windows working directory.

View original on GitHub ↗

19 Comments

github-actions[bot] · 4 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/27746
  2. https://github.com/anthropics/claude-code/issues/27463
  3. https://github.com/anthropics/claude-code/issues/17822

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

luiz00martins · 4 months ago

I've also ran on this error. API Error: EEXIST: file already exists, mkdir. I think I got it after trying to open Claude Code on the home directory once. After that, no prompt works (on any directory). Seems like Claude Code gets confused in that situation between the global and local .claude folders.

Purging my home directory .claude solved the issue.

luiz00martins · 4 months ago

Retract my statement: Even after purged, but the error returned the same day.

This makes Claude Code windows basically unusable. Will be returning to npm.

sstklen · 4 months ago

Hey! I ran into a similar pattern in our bug knowledge base and thought this might help.

What's happening: fs.mkdirSync (or fs.mkdir) called on ~/.claude without { recursive: true }. On Windows, this throws EEXIST if the directory already exists. Once .claude exists (e.g. from opening Claude Code in home dir), every subsequent mkdir call in the OAuth token path fails.

What worked for us:

Change all mkdir/mkdirSync calls for the .claude config directory (and its subdirectories) to use { recursive: true }, which is a no-op when the directory already exists. Specifically in the OAuth token storage path where the error originates.

// Before (throws EEXIST on Windows if dir exists):
fs.mkdirSync(configDir);
// or
await fs.promises.mkdir(configDir);

// After (no-op if dir already exists, creates parents too):
fs.mkdirSync(configDir, { recursive: true });
// or
await fs.promises.mkdir(configDir, { recursive: true });

Hope this helps! Let me know if it doesn't match your case — happy to dig deeper. 🦞

_Disclosure: This analysis is from Confucius Debug, an AI-powered community KB for agent bugs. Please verify before applying._

---
<sub>🦞 Confucius Debug — community knowledge base for AI agent bugs. Free to search via MCP.</sub>

BlueBit-jpg · 4 months ago

@sstklen that's JS, right? Not all that familiar, I'd hate to break something xD

BlueBit-jpg · 4 months ago

@luiz00martins the issue hasn't popped up for me when using WSL. If you haven't yet, it's worth giving that a try. Plus, you get to use Unix :D

sstklen · 4 months ago

@BlueBit-jpg You're right, that's JS — and since Claude Code is closed-source, you can't patch it yourself anyway. Sorry for not making that clearer.

What you can do right now:

  1. Delete the ~/.claude folder and restart Claude Code — this clears the stuck state (as @luiz00martins found)
  2. If it keeps coming back, the npm install (npm i -g @anthropic-ai/claude-code) seems more stable on Windows than the native binary
  3. WSL works too, as you discovered — the EEXIST bug is Windows-specific path handling
ahnbu · 4 months ago

Same mkdir EEXIST pattern in plugin marketplace code paths

Reporting the same root cause (fs.mkdir() without { recursive: true }) occurring in two additional code paths related to the plugin marketplace system.

Environment

  • Claude Code: v2.1.53 → v2.1.55 (reproduced on both)
  • OS: Windows 10 (MSYS_NT-10.0-26200)
  • Shell: MSYS2/Git Bash
  • Install: Standalone binary

Affected code paths

1. Adding a marketplace (/plugin > Add Marketplace):

EEXIST: file already exists, mkdir 'C:\Users\ahnbu\.claude\plugins\marketplaces'

2. Refreshing an existing marketplace (/plugin > Update marketplace):

Failed to refresh marketplace: EEXIST: file already exists, mkdir 'C:\Users\ahnbu\.claude\plugins'

3. Auto-update on session start (status bar, every session):

Failed to install Anthropic marketplace · Will retry on next startup

Reproduction

  1. Have at least one marketplace already installed (so ~/.claude/plugins/marketplaces/ exists)
  2. Try /plugin > Add Marketplace > enter any repo URL → EEXIST on mkdir 'marketplaces'
  3. Or select an existing marketplace > Update marketplace → EEXIST on mkdir 'plugins'

Workaround

Manual clone + edit known_marketplaces.json:

cd ~/.claude/plugins/marketplaces && git clone <repo-url>

Then add the entry to ~/.claude/plugins/known_marketplaces.json manually. The marketplace becomes visible in /plugin UI, but Update marketplace still fails with EEXIST.

Note

This is the same mkdir without { recursive: true } pattern as the OAuth path described in this issue, just in different code locations. See also #27860 (same pattern in Agent Teams). Seems like a codebase-wide issue on Windows.

sstklen · 4 months ago

@ahnbu Good find — the same mkdir without { recursive: true } pattern in the plugin marketplace code paths confirms this is a systemic issue, not just isolated to the OAuth token flow.

The two additional paths you identified (plugin install + plugin cache) follow the exact same pattern. Hopefully the fix gets applied to all fs.mkdir calls in one pass.

pedropaulovc · 4 months ago

Thanks to folks who realized this is related to auth, here's my simple workaround: /logout and log back in again.

johnw86 · 4 months ago

Cheers @pedropaulovc that worked for me.

raulblanko · 4 months ago

A workaround for those who use it as a VS Code plugin:

  1. Open a new Claude Code tab
  2. Press F1 -> Developer: Reload Window
  3. Open a recent session in the new Claude Code tab
  4. Continue conversation
kawabatakenji · 4 months ago

Still reproducing on v2.1.69 (VSCode Extension) / Windows 11

Environment:

  • Claude Code: v2.1.69 (VSCode Extension)
  • OS: Windows 11 (10.0.26200)
  • Shell: Git Bash (VSCode integrated terminal)

Reproduction:
The Write and Edit tools fail with EEXIST whenever the target file is inside an existing subdirectory.

Steps:

  1. Open a project with existing subdirectories (e.g. src/, Doc/, Temp/)
  2. Use the Write or Edit tool targeting a file inside any of those directories
  3. → Error occurs immediately

Error message:

EEXIST: file already exists, mkdir 'C:\Users\<username>\Documents\<project>\Temp'

The directory already exists, but the tool tries to create it without { recursive: true }, causing the failure. Same root cause as described in this issue.

Workaround: Use Bash tool with a Python script written to a temp file, then execute it.

XinMingmmm · 4 months ago

Additional reproduction: Write tool fails with EEXIST on existing directories

Environment: Windows 11 Pro (10.0.26200), PowerShell 7, Claude Code CLI

Reproduction

The Write tool (used internally by Claude Code to create files) consistently fails with EEXIST when the parent directory already exists. This affects any file write to an existing directory — not just OAuth/config paths.

Steps:

  1. Open Claude Code in any existing project directory (e.g. C:\Users\zhang\Desktop\my_project)
  2. Ask Claude to create a new file in the project root or any existing subdirectory
  3. Write tool fails:
Write(test_file.py)
 ⎿  Error: EEXIST: file already exists, mkdir 'C:\Users\zhang\Desktop\my_project'

Test results

| Scenario | Result |
|----------|--------|
| Write file to existing project root dir | ❌ EEXIST |
| Write file to existing subdirectory (metrics/) | ❌ EEXIST |
| Write file to new subdirectory (new_dir/) | ✅ Success |

Root cause confirmed

Verified with Node.js directly:

const fs = require('fs');

// Without recursive — throws EEXIST on existing dir
fs.mkdir('C:\Users\zhang\Desktop\my_project', (err) => {
  console.log('without recursive:', err?.code);  // → "EEXIST"
});

// With recursive — succeeds silently
fs.mkdir('C:\Users\zhang\Desktop\my_project', { recursive: true }, (err) => {
  console.log('with recursive:', err?.code || 'SUCCESS');  // → "SUCCESS"
});

This confirms the Write tool calls fs.mkdir() without { recursive: true } when ensuring parent directories exist before writing a file. The fix is the same as suggested in this issue — add { recursive: true } to all mkdir/mkdirSync calls.

Impact

This affects every file creation operation on Windows when the target directory already exists, making the Write tool unreliable for normal development workflows. The only workaround is to retry or pre-create files via Bash.

okas · 4 months ago

Root cause found: ReadOnly attribute on the user profile folder

I had the exact same symptoms — interactive mode hung with a blank terminal after the trust dialog, --print worked fine, and debug logs showed repeated EEXIST: file already exists, mkdir 'C:\Users\<username>' errors. Claude Code v2.1.69 on Windows 10 (build 26200.7922).

After extensive debugging, the culprit turned out to be the ReadOnly attribute on the user profile directory (C:\Users\<username>). This is commonly set by OneDrive's Known Folder Move feature and persists even after OneDrive is closed.

Diagnosis:

(Get-Item $env:USERPROFILE).Attributes
# Output: ReadOnly, Directory

Fix:

$folder = Get-Item $env:USERPROFILE
$folder.Attributes = $folder.Attributes -band (-bnot [System.IO.FileAttributes]::ReadOnly)

After removing the ReadOnly flag, interactive mode worked immediately — including from the home directory. The attribute did not return after restarting OneDrive.

Suggested fix for Claude Code: The mkdir calls in the startup/lock path should use { recursive: true } and handle EEXIST gracefully, or at minimum surface a clear error message instead of hanging silently. The ReadOnly attribute on user profile folders is extremely common on Windows due to OneDrive, so this likely affects many users.

transigmatpn-collab · 4 months ago

Root cause found: Windows Read-only (R) attribute on directories

The EEXIST error is NOT because fs.mkdirSync() lacks { recursive: true }. The actual cause is the parent directory has a Read-only (R) attribute — common on Windows, especially in project folders created by Git, Visual Studio, or Windows itself.

When fs.mkdirSync() encounters a directory with R attribute, it throws EEXIST instead of recognizing the directory already exists.

Why { recursive: true } is not the best fix

  • It only masks the error — the R attribute is still there and may cause other issues
  • Requires waiting for Anthropic to patch and release a new version
  • Users can't do anything until then

Self-healing fix — add to your User Memory file CLAUDE.md (/claude > /memory > Option 1. User memory)

## Windows EEXIST Fix for Write/Edit Tools
When Write/Edit tools fail with `EEXIST: file already exists, mkdir '<path>'`, the directory has a **Read-only (R) attribute**.
**Auto-fix steps:**
1. Run: `attrib '<parent_directory_with_forward_slashes>'` to check for `R` flag
2. If `R` found, run: `attrib -R '<directory_with_forward_slashes>'` to remove it
3. Retry Write/Edit — it will work
**Example:**
- Check: `attrib 'H:/project/CSFiles/Models'`
- Fix: `attrib -R 'H:/project/CSFiles/Models'`

This makes Claude Code automatically diagnose and fix the issue whenever it encounters EEXIST — no code update needed, no user intervention, works across all projects and sessions.

Environment

  • Windows 11
  • Claude Code v2.1.69
  • PowerShell 7.5.4
silver886 · 4 months ago

Additional reproduction: EEXIST on Windows directory junctions in config path

Reproduction

The config path at C:\Users\<username>\path\to\claude-code\config is a Windows directory junction (valid, functions as a real directory). The native build (exe) intermittently fails with:

API Error: EEXIST: file already exists, mkdir 'C:\Users\<username>\path\to\claude-code\config'

Key observations

| Scenario | Result |
|----------|--------|
| Native build (exe) — cold start | EEXIST error |
| npm package (cli.js) — same junction | Works correctly |
| Native build — after running npm package | Works temporarily |
| Native build — after some time passes | EEXIST error returns |

  • The npm package works correctly with the same directory junction and does not replace or modify it
  • After running the npm package, the native build temporarily works again on the exact same unchanged junction
  • After a while, the native build starts failing again
  • The junction itself is never modified by either version — verified with dir /AL

Analysis

This suggests the native build's runtime (Bun) handles fs.mkdir() differently than Node.js when encountering a directory junction. Node.js (used by the npm package) correctly recognizes the junction as an existing directory, while Bun's fs implementation does not — at least under certain initialization conditions.

This is the same mkdir without { recursive: true } root cause discussed in this thread, but the directory junction adds a consistent reproduction path. The intermittent "works after npm run" behavior may indicate that the npm package warms up some cached state that the native build then benefits from temporarily.

Environment

  • OS: Windows 11 Pro (10.0.26200.8037)
  • Claude Code: 2.1.76, native build (exe), direct download
  • Shell: PowerShell 7.5.5
github-actions[bot] · 3 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

github-actions[bot] · 2 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.