You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] plugin eval: sandboxed Bash cannot write the run workspace when TMPDIR is under /tmp ("Read-only file system") #104797
I have searched existing issues and this hasn't been reported yet
This is a single bug report (please file separate reports for different bugs)
I am using the latest version of Claude Code (tested on 2.1.309; 2.1.310 is out and not retested)
What's Wrong?
claude plugin eval creates each run's workspace under $TMPDIR (default /tmp), for example /tmp/claude-eval-XXXX/home/cwd. Bash in the sandbox then cannot write there. The eval cannot pass any case that writes a file with Bash.
What Should Happen?
Sandboxed Bash can write to the run's working directory, as the docs say ("Writes are confined to the run's workspace"), wherever TMPDIR points.
Error Messages/Logs
Exit code 1
/bin/bash: line 1: out.txt: Read-only file system
(trace cwd: /tmp/claude-eval-U7fnrz/home/cwd)
Steps to Reproduce
Linux (here: Ubuntu 24.04 container; bubblewrap and socat installed; the sandbox works).
One eval case: prompt.md with allowed_tools: [Bash], body Use the Bash tool to run: echo ok > out.txt, and a file_exists grader for out.txt.
claude plugin eval . --trust-plugin --allow-tools Bash --runs 1 --ablation none with default TMPDIR: score 0, error above.
TMPDIR=$HOME/tmp claude plugin eval ... (same command): score 1.
Is this a regression?
I don't know.
Claude Code Version
2.1.309 (Claude Code)
Claude Model
Other (claude-haiku-5-5 via --model)
Platform
Anthropic API
Operating System
Other Linux (Ubuntu 24.04 container on Docker Desktop, Windows 11 host)
Terminal/Shell
Non-interactive/CI environment
Additional Information
Not checked on a non-container Linux host. /tmp in the container is a tmpfs mount.
This error occurs because of an inversion in Linux VFS mount namespace ordering between the sandbox's /tmp isolation and the project directory bind-mount.
Root Cause
Most sandboxes isolate /tmp to prevent inter-process host pollution by mounting a fresh tmpfs over /tmp:
mount("tmpfs", "/tmp", "tmpfs", 0, "mode=1777");
If your workspace is located at /tmp/eval-123/cwd:
If the sandbox bind-mounts /tmp/eval-123/cwdbefore masking /tmp with tmpfs, the new tmpfs mount completely shadows and hides the workspace mount, turning writes into errors or sending them into an unmapped tmpfs.
Conversely, if /tmp is remounted read-only (MS_RDONLY) as a security measure, any directory underneath /tmp inherits the read-only flag from the VFS super-block unless explicitly re-bound and remounted MS_BIND | MS_REC.
The Fix
To support projects located in /tmp, follow this mount sequence:
Check for Root Equality:
if project_root != Path::new("/tmp"){// Only mount private tmpfs over /tmp if the project itself isn't /tmpmount_private_tmpfs("/tmp","mode=1777")?;}
Bind-Mount the CoW Workspace Second:
Always bind-mount the CoW overlay (or working directory) after the tmpfs for /tmp is configured. If the workspace is inside /tmp, recreate the directory structure inside the new tmpfs before bind-mounting:
let _ = std::fs::create_dir_all(project_root);mount(merged_overlay, project_root,NULL,MS_BIND | MS_REC,NULL)?;
Landlock Ruleset Ordering:
In your Landlock ruleset, ensure both the project root descriptor and /tmp descriptor are given AccessFs::from_all(abi). When Landlock evaluates path access, having the project root descriptor registered ensures descendant files within the workspace receive explicit write access regardless of ancestor mounts.
Activity
6t9xstar commentedon Nov 5, 2026
This error occurs because of an inversion in Linux VFS mount namespace ordering between the sandbox's
/tmpisolation and the project directory bind-mount.Root Cause
Most sandboxes isolate
/tmpto prevent inter-process host pollution by mounting a freshtmpfsover/tmp:If your workspace is located at
/tmp/eval-123/cwd:/tmp/eval-123/cwdbefore masking/tmpwithtmpfs, the new tmpfs mount completely shadows and hides the workspace mount, turning writes into errors or sending them into an unmapped tmpfs./tmpis remounted read-only (MS_RDONLY) as a security measure, any directory underneath/tmpinherits the read-only flag from the VFS super-block unless explicitly re-bound and remountedMS_BIND | MS_REC.The Fix
To support projects located in
/tmp, follow this mount sequence:Always bind-mount the CoW overlay (or working directory) after the tmpfs for
/tmpis configured. If the workspace is inside/tmp, recreate the directory structure inside the new tmpfs before bind-mounting:In your Landlock ruleset, ensure both the project root descriptor and
/tmpdescriptor are givenAccessFs::from_all(abi). When Landlock evaluates path access, having the project root descriptor registered ensures descendant files within the workspace receive explicit write access regardless of ancestor mounts.