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
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

  1. Open a Claude Code session in a repository (or in a worktree of it).
  2. In a normal terminal (outside Claude Code): rm -f <repo>/.git/config.lock
  3. Let Claude run any sandboxed Bash command, even a read-only one such as stat <repo>/.git/config.lock.
  4. 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> prints error: could not lock config file .git/config / warning: update of config-file failed; git checkout -b <branch> origin/main fails with unable to write upstream branch configuration; git worktree add -b … stops half-way; git push -u cannot record the upstream.
  • A scratch repository created under $TMPDIR inside the sandbox is not affected (git config --local works, no placeholder appears), so the placeholder is tied to the session repository's .git directory (the one on the sandbox's write allow-list).
  • No settings layer mentions config.lock (~/.claude/settings.json, project settings.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.lock to the sandbox write allow-list, because that would remove the .git/config protection (e.g. core.hooksPath).

View original on GitHub ↗