[BUG] /export fails with EEXIST on Windows when the target directory has the ReadOnly attribute (Bun mkdir recursive bug — root cause + 1-line fix)

Status Open
Reported on v2.1.218
Maintainer reply None cached
Activity 1 comment · opened Jul 23, 2026

Bug Description

/export (with or without a filename argument) fails on Windows native builds:

❯ /export
  ⎿  Failed to export conversation: EEXIST: file already exists, mkdir 'C:\Users\<user>\Documents\<project>'

The path in the error is the session CWD — the directory that already exists and should be a no-op for a recursive mkdir.

This is a re-report of #52161, which was closed as stale by the bot without a fix. It still reproduces on the latest version (2.1.218). This report adds the verified root cause.

Root cause (verified)

The export code itself is correct — it calls fs.promises.mkdir(path.dirname(target), { recursive: true }), which per Node semantics must succeed silently when the directory exists.

The bug is in Bun, the runtime the native Windows binary is compiled with: on Windows, mkdir(..., { recursive: true }) throws EEXIST when the existing directory carries the ReadOnly attribute. Plain directories are unaffected.

  • Upstream bug: oven-sh/bun#34413 (fix merged upstream 2026-07-16, not yet in a Bun release bundled by Claude Code), also oven-sh/bun#29521.
  • Reproduced independently of Claude Code with plain Bun 1.3.1 on Windows 11:
// dir exists and has the ReadOnly attribute (attrib +R) — e.g. anything OneDrive-synced,
// Windows special folders like Documents, or folders stamped R by sync/backup tools
await require('fs/promises').mkdir('C:/Users/x/Documents', { recursive: true });
// Bun: EEXIST — Node: resolves undefined

This is why the bug looks intermittent across users/machines: it only bites when the session CWD (or the export target's parent) happens to have the R attribute — which OneDrive sets on everything it syncs, so OneDrive users are hit hardest (matches the OneDrive path in #52161).

Reproduction

  1. Windows, native install.
  2. attrib +R . in any project directory (or use any OneDrive-synced dir).
  3. Run claude, then /export anything.txtEEXIST.
  4. attrib -R ./export works.

Suggested fix

Same guard already applied for the identical Bun bug in the session-env mkdir (#59622): wrap the export-path mkdir so an existing directory can't fail —

if (!existsSync(dir)) await mkdir(dir, { recursive: true });
// or: await mkdir(dir, {recursive:true}).catch(e => { if (e.code !== 'EEXIST') throw e; })

Longer term, bumping the bundled Bun to a release containing the fix for oven-sh/bun#34413 removes the whole class of Windows EEXIST bugs.

Environment Info

  • Platform: win32 (Windows 11)
  • Terminal: windows-terminal
  • Version: 2.1.218 (native)

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗