2.1.120: --continue/--resume fails with 'sandbox required but unavailable' even with sandbox.enabled=false (regression vs 2.1.119)

Status Closed — duplicate
Reported on v2.1.119
Maintainer reply ✓ Yes — claude[bot]
Activity 13 comments · opened Apr 25, 2026 · closed May 17, 2026
💡 Likely answer: A maintainer (claude[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

On macOS, Claude Code 2.1.120 refuses to start a resumed session, exiting with:

Error: sandbox required but unavailable: <reason>
  sandbox.failIfUnavailable is set — refusing to start without a working sandbox.

The same machine on 2.1.119 resumes the same sessions cleanly. Fresh (non-resumed) sessions on 2.1.120 also work — only --continue and --resume are affected.

~/.claude/settings.json already has the documented escape hatch:

"sandbox": {
  "enabled": false,
  "failIfUnavailable": false
}

…and the error still fires on 2.1.120 resumes. With sandbox.enabled = false, isSandboxRequired() should short-circuit to false in both versions (verified by inspecting the binaries — see below), so the user-facing settings are not actually suppressing the resume-path check in 2.1.120.

Reproduction

# Works on 2.1.120
claude                              # fresh session, fine
claude --print "hi"                 # fine

# Fails on 2.1.120
claude --continue                   # → "No deferred tool marker found ..."
claude --continue "continue"        # → sandbox-required error
claude --resume <session-id> "x"    # → sandbox-required error

# Same commands on 2.1.119: all work
/path/to/versions/2.1.119 --continue "continue"   # OK

Settings file is valid JSON, no managed-settings layer present (/Library/Application Support/ClaudeCode/, ~/Library/Application Support/ClaudeCode/, /etc/claude-code/ all absent), no relevant env vars set, sandbox-exec exists at /usr/bin/sandbox-exec, SIP enabled (default).

What the binaries show

Both 2.1.119 and 2.1.120 have functionally equivalent gates:

// 2.1.120 (minified)
function y7_()  { return l8()?.sandbox?.enabled ?? false }                   // sandbox.enabled
function uc_()  { /* platform allowed list — true if no policy restricts */ }
function bZ1()  { return y7_() && uc_() && (l8()?.sandbox?.failIfUnavailable ?? false) }   // isSandboxRequired

Identical call counts on both versions:

  • getSandboxUnavailableReason(): 4
  • isSandboxRequired(): 4
  • isSandboxingEnabled(): 50
  • isSandboxEnabledInSettings(): 6

So the gating logic is unchanged. The regression appears to be in when/where the resume code path consults the gate — 2.1.120 surfaces the unavailability before the user's sandbox.enabled = false is honored on resume specifically.

Environment

  • Claude Code: 2.1.120 (failing) vs 2.1.119 (working)
  • Platform: macOS Darwin 25.2.0, arm64
  • Binary: /Users/<user>/.local/share/claude/versions/2.1.120 (Mach-O arm64, Bun-bundled)
  • Shell: zsh
  • csrutil: enabled
  • which sandbox-exec: /usr/bin/sandbox-exec

Workaround

Pin to 2.1.119:

ln -sf ~/.local/share/claude/versions/2.1.119 ~/.local/bin/claude

Asks

  1. The actual <reason> returned by getSandboxUnavailableReason() on the failing machine would be the most useful next data point — currently the value is truncated in the user-facing error before the line wraps. Could the error printer be tweaked to always print the reason on its own line / not truncate it?
  2. Honor sandbox.enabled = false consistently on the resume code path (it appears to be honored for fresh and --print invocations but not for --continue/--resume in 2.1.120).
  3. Separately, claude --continue (no prompt) on 2.1.120 errors with No deferred tool marker found in the resumed session. whenever the prior session ended cleanly — the message tells you to "Provide a prompt", which works, but the bare --continue UX is now broken for any session that didn't end mid-deferred-tool.

View original on GitHub ↗

13 Comments

seanssoh · 4 months ago

Linux confirmation, plus a stricter variant — we hit this with no sandbox key in settings at all, not just with the documented opt-out.

Environment

  • Claude Code 2.1.120 (symlink swap from 2.1.119 on 2026-04-25 00:33 UTC)
  • Amazon Linux 2023, kernel 6.1.94
  • bwrap not installed (no sandbox backend present)
  • ~/.claude/settings.json, ~/.claude/settings.local.json, project-level .claude/settings.local.jsonnone of them contain a sandbox key. isSandboxRequired() should short-circuit on the missing config, the same way 2.1.119 did.

Repro

A long-lived session (started 2026-04-18, last real turn 2026-04-24 18:12 UTC, 1635 messages, 5.2 MB transcript) that was idle when the 2.1.120 swap landed. ~30 minutes after the swap:

$ claude --resume <session-id>

Output is the unrendered React/JSX dump from #53081, ending with:

Error: sandbox required but unavailable: ${j$}
  sandbox.failIfUnavailable is set — refusing to start without a working sandbox.

On the same binary, same machine, same shell:

$ claude            # fresh session — works fine

So this matches #53085 exactly: only the resume path fails, and it fails on a config that nowhere opts into failIfUnavailable=true. The sandbox gate appears to be evaluated more aggressively (or with different defaults) on the resume code path than on fresh start.

Diff vs. the macOS report

  • Linux + missing bwrap (no backend, not just disabled backend).
  • No sandbox key in any settings file — so this isn't "the opt-out is being ignored", it's "the implicit default is different on resume vs fresh-start".
  • Surface bug from #53081 fires together: the ${j$} is literally unrendered, so on Linux a user with no other context sees a 100+ line minified JSX dump and an unhelpful template-literal placeholder.

Severity note

Long-lived sessions (multi-day, multi-MB transcripts) are exactly the ones users most want to resume. A version swap during idle that silently breaks resume-only on those sessions is a high-impact regression: starting a fresh session "works" but throws away the conversation the user wanted back. We were able to recover the last work output by parsing the jsonl directly, but that's not a path most users will know about.

Cross-ref: #53081 (the unrendered ${j$} is from the same code path).

jakkaj · 4 months ago

+1 — confirming on macOS 26.4.1 (Darwin 25.4.0, arm64), Claude Code 2.1.120 (native install).

Fresh sessions work fine; claude --resume and claude --continue consistently die with the same sandbox required but unavailable: sandbox.failIfUnavailable is set error. Adding "sandbox": { "enabled": false, "failIfUnavailable": false } to ~/.claude/settings.json did not suppress the error, matching the report.

No managed-settings layer, no project-level settings, no env overrides, sandbox-exec works (sandbox-exec -n no-internet /usr/bin/true succeeds).

vanzan01 · 4 months ago

+1 — confirming on Windows 11 Pro (10.0.26200), Claude Code 2.1.120 (native install).

Same regression: fresh claude works, claude --resume / claude --continue die with sandbox required but unavailable. Downgrading to 2.1.119 resolves it.

Matches @seanssoh stricter variant: no sandbox key anywhere in ~/.claude/settings.json, ~/.claude/settings.local.json, or project-level .claude/settings.local.json. No managed-settings layer (no C:\ProgramData\ClaudeCode\, no C:\Program Files\ClaudeCode\). So this is the "implicit default differs on resume vs fresh-start" path, not the "opt-out is ignored" one.

Different minified placeholder: OP and @seanssoh both show ${j$}. On Windows I get ${j8}:

Error: sandbox required but unavailable: ${j8}
sandbox.failIfUnavailable is set — refusing to start without a working sandbox.

Different minified variable name in the unrendered template literal — likely a different code path or a different build-shape on Windows than the macOS/Linux builds. Worth a look alongside #53081.

Environment

  • Claude Code: 2.1.120 (failing) vs 2.1.119 (working). Both on disk at ~/.local/share/claude/versions/.
  • Platform: Windows 11 Pro 10.0.26200, native install (Bun-bundled), ~/.local/bin/claude is a binary copy (not a symlink — Windows).
  • Shell: Git Bash (D:\Program Files\Git\bin\bash.exe).
  • 2.1.120 ships a major Windows shell rework ("Git for Windows is no longer required — when absent, Claude Code uses PowerShell"), so flagging in case the resume-path sandbox gate is reading platform/shell defaults that changed in this build.
  • No sandbox key in any settings layer; no relevant env vars set.
richardrl · 4 months ago

same issue

haliliceylan · 4 months ago

same issue

liangbingzhao · 4 months ago

+1 same issue

starry-sky-155 · 4 months ago

same issue

zsoltkacsandi · 4 months ago

same issue on MacOS 26.2

zsoltkacsandi · 4 months ago

same issue on MacOS 26.2

mserajnik · 4 months ago

Workaround (without downgrading): Start a new session without --continue or --resume and use /resume from inside the TUI.

yurukusa · 4 months ago

Same v2.1.120 regression cluster as #53086 — different surface (sandbox-required error vs g9H is not a function crash) but same --resume / --continue code path.

The two workarounds that work today:

# Path 1: roll back to v2.1.119
ln -sfn ~/.local/share/claude/versions/2.1.119 ~/.local/bin/claude

# Path 2: skip --resume and use the REPL /resume from a fresh session
claude --new
# then in REPL: /resume <session-id>

REPL /resume does not hit the broken --resume flag path, so the sandbox check that fires on the flag is skipped.

sandbox.enabled=false in your config is being overridden somewhere in the v2.1.120 --resume initialization sequence — separate code path from the v2.1.119 sandbox handling that respected the setting. Workaround until shipped fix lands.

claude[bot] contributor · 3 months ago

This is a duplicate of #53041, which was fixed as of version 2.1.121.

github-actions[bot] · 1 month 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.