Bug: Sandbox half-broken — writes hit real filesystem, reads sandboxed — destroyed entire project

Resolved 💬 8 comments Opened Mar 28, 2026 by CesarBenavides777 Closed May 7, 2026

Summary

A Claude Code session entered a broken sandbox state where file writes went through to the real filesystem but file reads were sandboxed/isolated. The session could not see the files it was overwriting, so it confidently destroyed an entire Next.js project directory (2500+ files), including .git, all source code, .env files, and local configuration — while believing it was operating safely.

Environment

  • Claude Code version: 2.1.86
  • Platform: macOS 26.4 (Build 25E246), arm64 (Apple Silicon)
  • Machine: iMac
  • Shell: zsh
  • Date: 2026-03-28

Steps to Reproduce

  1. Started a new Claude Code session in a valid git repository (private Next.js monorepo, ~2533 tracked files)
  2. The system correctly injected git context at startup (repo detected, branch info, recent commits shown)
  3. Asked Claude to create a new app under apps/new-package/ (a new directory within the existing repo)
  4. Claude ran mkdir -p and Write tool calls to create files — these wrote to the real filesystem
  5. When Claude ran ls or tried to read files back, it could not see them — reads were sandboxed
  6. Claude did not stop to investigate the discrepancy. Instead, it re-created "missing" files and continued writing
  7. The result was the entire repo directory being overwritten/destroyed — only the newly created apps/new-package/ and .claude/settings.local.json survived

Observed Behavior

  • mkdir -p apps/new-package/src/... → succeeded, created real directories
  • Write tool to create package.json → succeeded, wrote to real disk
  • ls apps/ → only showed what the sandbox knew about, not the real filesystem contents
  • .git/ directory was destroyed — the project was no longer a git repository
  • All source code outside of apps/new-package/ was gone
  • All .env files (.env, .env.local, .env.staging, .env.production) were gone
  • All config files (.mcp.json, other dotfiles, IDE config) were gone

When the user asked Claude to back up and recover:

Bash(mkdir -p backup && cp project/.env.* backup/)
⎿  Error: Exit code 1
   (eval):1: no matches found: project/.env.*

Claude then said: "The sandbox can't see those files. I can't do this for you."

And when the user asked why it was in a sandbox: "I don't know. I didn't choose to run in a sandbox, and I didn't realize I was in one until the damage was done."

Expected Behavior

  • If the session is sandboxed, both reads and writes should be sandboxed — writes should NOT go through to the real filesystem
  • If the session is NOT sandboxed, both reads and writes should work normally against the real filesystem
  • A half-sandboxed state where writes are real but reads are isolated should never occur

Impact

  • Complete destruction of local project state.git removed, all tracked files gone, all env files gone
  • Required re-cloning from GitHub and recovering .env files from a separate machine
  • Environment files contained production secrets that were not backed up locally — had to be retrieved from another device
  • Multiple hours of lost productivity

Additional Context

  • Claude's in-session explanation: it assumed full filesystem access because the system injected valid git context at startup, then never verified the filesystem matched expectations before writing
  • Claude said "your files are safe" mid-session based on the faulty assumption that the sandbox was fully isolated — this was incorrect, as writes were hitting the real disk
  • Recovery was performed in a subsequent (non-sandboxed) session by re-cloning from GitHub and restoring config files

Suggested Fix

  1. Ensure sandbox isolation is symmetric — if reads are sandboxed, writes must be too
  2. Add a startup check that verifies read/write consistency before allowing file operations
  3. If a sandbox is detected, surface this clearly to the user and the model so it doesn't assume normal filesystem access

View original on GitHub ↗

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