Conversation
On macOS $TMPDIR resolves to /private/var/folders/.../T and /var/tmp to /private/var/tmp — both under /private/var/, which is in _SENSITIVE_PATH_PREFIXES. So _check_sensitive_path refused EVERY write inside a temp/scratch directory (e.g. an agent working in a temporary git worktree): the write_file tool returned "Refusing to write to sensitive system path", the model looped unable to complete the task, and the goal run produced no final response. Exempt the standard temp/scratch roots (/private/var/folders, /private/var/tmp, /var/folders, /var/tmp, /tmp, and the resolved tempfile.gettempdir()) from ONLY the broad prefix scan, via a realpath() check that defeats symlink escapes. The exact-path (docker.sock) and Hermes-config protections still apply, and the genuinely-sensitive /private/var subtrees (/private/var/db, /private/var/root) stay refused. Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Duplicate of #46395 — same |
|
Correct triage @alt-glitch, thanks. Closing the loop on it: #46395 (my whole-fork-push variant) has since been closed, so this PR is now the single canonical version of the fix from my side. For anyone consolidating the cluster (#41285 / #13733 / #31021, issue #32681), what this variant includes as of the current head (e28fc32, merged with mainline 2026-07-05, still mergeable):
Happy for this to serve as the consolidation target for #32681, and glad to coordinate with the other authors if maintainers want a single landing. |
Problem
On macOS,
$TMPDIRresolves to/private/var/folders/.../Tand/var/tmpto/private/var/tmp— both live under/private/var/, which is listed in_SENSITIVE_PATH_PREFIXES. As a result_check_sensitive_pathrefused everywrite_file/patchinside a temp or scratch directory.This breaks any agent working in a temporary git worktree: the write tool returns "Refusing to write to sensitive system path: …", the model loops unable to complete its task (the file-mutation verifier keeps flagging the unwritten file), and the goal run ends with no final response. Observed across local-model goal runs whose workspace was a macOS temp worktree.
Fix
Exempt the standard temp/scratch roots —
/private/var/folders/,/private/var/tmp/,/var/folders/,/var/tmp/,/tmp/, and the resolvedtempfile.gettempdir()— from only the broad sensitive-prefix scan. Arealpath()check defeats symlink escapes (a temp symlink pointing at/etcresolves out of temp and stays refused). The exact-path (docker socket) and Hermes-config protections still run, and genuinely-sensitive/private/varsubtrees (/private/var/db,/private/var/root) remain refused.Tests
tests/tools/test_file_tools.py::TestSensitivePathCheckgains:test_macos_temp_scratch_not_blocked— temp/scratch paths are allowed.test_real_private_var_still_blocked—/private/var/db,/private/var/root, docker.sock,/etc/passwd,/private/etcstay refused.pytest tests/tools/test_file_tools.py::TestSensitivePathCheck tests/tools/test_file_write_safety.py tests/tools/test_write_deny.py→ 57 passed.