[BUG] /sandbox picker shows option 2 as (current) when runtime is option 1; picker selection appears to be no-op (v2.1.105)

Resolved 💬 1 comment Opened Apr 13, 2026 by Nnode Closed May 24, 2026

Summary

In Claude Code v2.1.105, the /sandbox picker UI displays option 2 ("Sandbox BashTool, with regular permissions") as (current) even though the runtime is demonstrably in option 1 (autoAllowBashIfSandboxed: true). Additionally, selecting option 1 in the picker appears to be a no-op: it does not write to ~/.claude/settings.json or ~/.claude/settings.local.json, and the (current) label does not update after selection.

Environment

  • Claude Code: v2.1.105 (verified via claude --version)
  • macOS (Darwin 25.4.0)
  • No managed settings, no CLAUDE_CODE_* overrides affecting sandbox

Reproduction

  1. Configure ~/.claude/settings.json with a sandbox block that sets enabled: true, autoAllowBashIfSandboxed: true, plus network allowedDomains, filesystem allowWrite, and filesystem denyRead arrays.
  2. Optionally, also set sandbox.autoAllowBashIfSandboxed: true in one or more project-level .claude/settings.local.json files.
  3. Ensure ~/.claude/settings.local.json is {} (no persisted picker selection).
  4. Start a fresh top-level claude session inside a project directory that has a project-local sandbox block.
  5. Observe the top-bar status banner — it correctly reads: ✓ Sandbox enabled with auto-allow for bash commands
  6. Run ls (or any benign Bash command). It executes without a permission prompt — runtime is option 1.
  7. Open /sandbox. The picker shows: 2. Sandbox BashTool, with regular permissions (current) — option 2 is labelled (current) despite runtime being option 1.
  8. Navigate to option 1 and select it.
  9. Re-open /sandbox. Option 2 is still labelled (current).
  10. Check ls -l ~/.claude/settings.json ~/.claude/settings.local.json — neither file's mtime has changed. The picker selection did not persist to either user-level settings file.

Expected

Either:

  • The picker's (current) indicator should reflect the effective runtime sandbox mode (merged across settings layers), OR
  • Selecting option 1 should persist the choice to settings.local.json and update the (current) label on subsequent opens.

Actual

  • Picker shows option 2 as (current) regardless of runtime.
  • Picker selection of option 1 writes nowhere (file mtimes unchanged).
  • Runtime and UI label are desynchronised.

Hypothesis

The picker's (current) rendering appears to compare settings against a fixed set of named presets (option 1 = auto-allow, option 2 = regular permissions, option 3 = no sandbox) rather than evaluating the effective merged sandbox block. A custom sandbox block with additional fields like failIfUnavailable, network, or filesystem may not match any preset, causing a fall-through to option 2 labelling.

Impact

Cosmetic only — runtime behaviour is correct. But it's confusing enough to trigger a full investigation, and it may cause users to believe auto-allow is disabled when it isn't, leading to unnecessary reconfiguration attempts.

Related

  • #44791 — /model silently wipes sandbox allowlist (sibling bug: /slash-command mutating sandbox state unexpectedly)
  • #46111 — --settings flag resolves sandbox filesystem paths relative to file, not project root
  • #31675 — [DOCS] Permissions and settings docs missing bash auto-approval allowlist enumeration

View original on GitHub ↗

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