Sandbox leaves a real 0-byte read-only .git/config.lock on the host, breaking git config writes in the user's own terminal
Status Open
Maintainer reply None cached
Workaround ✓ Mentioned in description ↑
Activity 0 comments · opened Oct 15, 2026
Summary
The Bash sandbox (bubblewrap, Linux) write-protects the session repository's .git/config by placing a placeholder at .git/config.lock. That placeholder is created as a real file on the host filesystem (0 bytes, mode 0444) and is never removed when the command exits. Afterwards every git operation that needs to write .git/config fails with error: could not lock config file .git/config — also in the user's own terminal, outside Claude Code.
Environment
- Claude Code desktop app (Code tab), session running in a git worktree of the repository
- Linux (Ubuntu VPS), bubblewrap sandbox enabled (default settings)
- git 2.x; two repositories on the same machine show the same file
Steps to reproduce
- Open a Claude Code session in a repository (or in a worktree of it).
- In a normal terminal (outside Claude Code):
rm -f <repo>/.git/config.lock - Let Claude run any sandboxed Bash command, even a read-only one such as
stat <repo>/.git/config.lock. - In the normal terminal:
stat <repo>/.git/config.lock
Observed
- The file exists on the host:
-r--r--r--, 0 bytes, mtime equal to the time of the sandboxed command (reproduced several times during one session; the mtime moves with each sandboxed command). - Later, in the user's terminal:
git branch -D <branch>printserror: could not lock config file .git/config/warning: update of config-file failed;git checkout -b <branch> origin/mainfails withunable to write upstream branch configuration;git worktree add -b …stops half-way;git push -ucannot record the upstream. - A scratch repository created under
$TMPDIRinside the sandbox is not affected (git config --localworks, no placeholder appears), so the placeholder is tied to the session repository's.gitdirectory (the one on the sandbox's write allow-list). - No settings layer mentions
config.lock(~/.claude/settings.json, projectsettings.json/settings.local.json, the merged session settings file,/etc/claude-code/managed-settings.json).
Expected
The .git/config write-protection placeholder should exist only inside the sandbox mount namespace (e.g. bind-mounted from a tmpfs), or be removed when the sandboxed command exits. It should never persist on the host filesystem, and it must not break git in the user's own terminal.
Workaround we use
- Before any config-writing git command in the terminal:
rm -f <repo>/.git/config.lock(it comes back on the next sandboxed command). - Inside Claude sessions:
git switch --no-track -c …,git push origin HEAD:refs/heads/<branch>,git branch --no-track …+git worktree add <path> <branch>. - We deliberately do not add
.git/config.lockto the sandbox write allow-list, because that would remove the.git/configprotection (e.g.core.hooksPath).