Bug Description
The sandbox sets TMPDIR=/tmp/claude/ and allows writes there, but does not set TMPPREFIX. Zsh uses $TMPPREFIX (default: /tmp/zsh) for heredoc temp files — not $TMPDIR. This means any heredoc in a sandboxed zsh command fails with:
(eval):1: can't create temp file for here document: read-only file system
Any command using heredocs (<<EOF, <<-EOF, <<< herestrings) will fail.
Reproduction
Shell: zsh (e.g. WSL2 Ubuntu on Windows 11)
# This fails in sandbox mode:
git commit -m "$(cat <<'EOF'
Multi-line message
EOF
)"
Root Cause
Zsh has a separate variable $TMPPREFIX (documented in zshparam(1)) that controls where heredoc temp files are created. Its default value is /tmp/zsh. The sandbox allows writes to /tmp/claude/ but blocks writes to /tmp/zsh*.
| Variable |
Value |
Sandbox Write? |
TMPDIR |
/tmp/claude |
Allowed |
TMPPREFIX |
/tmp/zsh (default) |
Blocked |
Suggested Fix
When the shell is zsh, the sandbox initialization should also set:
export TMPPREFIX=/tmp/claude/zsh
This would make heredocs work transparently, just as setting TMPDIR makes other temp file operations work.
Workarounds
- Use
git commit -F /tmp/claude/msg.txt instead of heredocs
- Use multiple
-m flags: git commit -m "Subject" -m "Body"
- Use ANSI-C quoting:
git commit -m $'Subject\nBody'
- Prefix commands with
TMPPREFIX=/tmp/claude/zsh
- Use
dangerouslyDisableSandbox: true (defeats the purpose)
Environment
- Claude Code on WSL2 Ubuntu (Windows 11)
- Shell: zsh
- Platform: linux (WSL2)
Bug Description
The sandbox sets
TMPDIR=/tmp/claude/and allows writes there, but does not setTMPPREFIX. Zsh uses$TMPPREFIX(default:/tmp/zsh) for heredoc temp files — not$TMPDIR. This means any heredoc in a sandboxed zsh command fails with:Any command using heredocs (
<<EOF,<<-EOF,<<<herestrings) will fail.Reproduction
Shell: zsh (e.g. WSL2 Ubuntu on Windows 11)
Root Cause
Zsh has a separate variable
$TMPPREFIX(documented inzshparam(1)) that controls where heredoc temp files are created. Its default value is/tmp/zsh. The sandbox allows writes to/tmp/claude/but blocks writes to/tmp/zsh*.TMPDIR/tmp/claudeTMPPREFIX/tmp/zsh(default)Suggested Fix
When the shell is zsh, the sandbox initialization should also set:
export TMPPREFIX=/tmp/claude/zshThis would make heredocs work transparently, just as setting
TMPDIRmakes other temp file operations work.Workarounds
git commit -F /tmp/claude/msg.txtinstead of heredocs-mflags:git commit -m "Subject" -m "Body"git commit -m $'Subject\nBody'TMPPREFIX=/tmp/claude/zshdangerouslyDisableSandbox: true(defeats the purpose)Environment