[BUG] WSL2: managed-settings.json makes the Bash sandbox build a Windows-side mask path with an empty username (/mnt/c/Users/.claude), breaking every command

Status Open
Reported on v2.1.217
Maintainer reply None cached
Activity 2 comments · opened Jul 22, 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?

One-line

On WSL2, the mere presence of /etc/claude-code/managed-settings.json makes the sandbox add a bind-mount mask for the Windows-side user config dir, but the path is built with an empty username/mnt/c/Users/.claude instead of /mnt/c/Users/<user>/.claude. That's the admin-only C:\Users root, so bwrap fails with Can't mkdir … Permission denied and aborts every sandboxed command. With sandbox.failIfUnavailable: true, Claude Code won't start at all. Not fixable from user config.

Environment

  • Claude Code 2.1.217 (latest; claude update says up to date), native installer at ~/.local/bin/claude
  • WSL2 (Ubuntu) on Windows 11; project on DrvFs (/mnt/c/...)
  • Sandbox backend: bubblewrap
  • HOME=/home/<username> (correct), USERNAME=<username>, USERPROFILE=/mnt/c/Users/<username> in the shell

Symptom (every Bash tool call, ! prefix, and hooks)

​``
bwrap: Can't mkdir /mnt/c/Users/.claude: Permission denied
`
Also observed as the base collapses:
/mnt/c/Users/.mcp.json, and (with USERPROFILE unset) /mnt/c/.mcp.json`.

The target should be the Windows user config C:\Users\<username>\.claude = /mnt/c/Users/<username>/.claude. Instead the username segment is empty → /mnt/c/Users/.claude.

Exact trigger (bisected)

  • Managed file present → broken. Managed file absent → sandbox works fully from the project .claude/settings.json (identical sandbox.enabled: true, denies, credential scrub, domain lockdown).
  • Trigger is the presence of the managed file, independent of its contents across the variants tried. It is not the env/CLAUDE_CODE_SUBPROCESS_ENV_SCRUB key, not allowManagedDomainsOnly, not failIfUnavailable.

Why it's a Claude Code bug, not a config problem (all verified)

  • Not env-fixable. USERNAME=<username> and USERPROFILE=/mnt/c/Users/<username> are set (via WSLENV=USERPROFILE/p:USERNAME), yet the mask username is still empty. Clearing WSLENV makes it worse (/mnt/c/Users//mnt/c/), showing the base tracks dirname($USERPROFILE) while the username leaf is separately empty. Correct behaviour would be to use $USERPROFILE directly.
  • Not fixable by pre-creating the target. Creating C:\Users\.claude (+ siblings) as writable dirs/files does not resolve it — bwrap still fails, so this is not merely a missing mountpoint.
  • Not cwd. Reproduces from a Linux-fs cwd (~) too, as long as the managed file is deployed.
  • Not version. Reproduces on latest (2.1.217).

Root cause (hypothesis)

Under managed policy, Claude Code masks the settings/config sources so a sandboxed process can't tamper with them, and on WSL it includes the Windows-side user config dir. The Windows path is constructed as roughly dirname($USERPROFILE) + "/" + <username> with <username> empty in the sandbox-setup context, yielding /mnt/c/Users/.claude (the admin-only Users root). bwrap can't create a mountpoint there → hard abort.

Impact

  • Bash sandbox unusable on WSL whenever managed settings are deployed.
  • With failIfUnavailable: true, Claude Code refuses to launch — so an org that enforces managed policy on WSL is fully blocked from running Claude Code.
  • Same family as the closed #26722 / #17727 and the C:\Program Files\ClaudeCode mask issue, but this variant is triggered by managed-settings presence and adds an empty-username path bug.

Suggested fix

  1. Build the Windows-side config mask from $USERPROFILE directly (don't recompose it from dirname + a possibly-empty username).
  2. On WSL, if a mask target's mountpoint can't be created (DrvFs / admin-only root), skip that single mask with a warning instead of aborting the whole sandbox.
  3. Don't require masking Windows-side paths at all when running under WSL — the enforcement point is /etc/claude-code/managed-settings.json on the Linux side.

Note on debug capture

The malformed bwrap argv is not surfaced by claude --debug or CLAUDE_CODE_DEBUG=1 (tested in -p mode; no sandbox/bwrap lines logged). Happy to run any trace flag a maintainer suggests to dump the exact bind-mount arguments.

Minimal repro

  1. WSL2, Claude Code 2.1.217, project on /mnt/c/....
  2. Deploy a managed-settings.json to /etc/claude-code/managed-settings.json (failure was independent of contents across the variants we tried).
  3. Start claude, run a Bash command → bwrap: Can't mkdir /mnt/c/Users/.claude: Permission denied.
  4. sudo rm /etc/claude-code/managed-settings.json, retry → works.

What Should Happen?

Either fix as suggested or provide a workaround to fix the sandbox with managed settings deployed.

Error Messages/Logs

Claude just keeps repeating that bash is dead or the sandbox is unusable. ! commands run into: 
`bwrap: Can't mkdir /mnt/c/Users/.claude: Permission denied`

Steps to Reproduce

WSL2, Claude Code 2.1.217, project on /mnt/c/....
Deploy a managed-settings.json to /etc/claude-code/managed-settings.json (failure was independent of contents across the variants we tried).
Start claude, run a Bash command → bwrap: Can't mkdir /mnt/c/Users/.claude: Permission denied.
sudo rm /etc/claude-code/managed-settings.json, retry → works.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.217

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

WSL (Windows Subsystem for Linux)

Additional Information

_No response_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗