Background session cannot edit a repo nested under a non-git cwd: write guard demands EnterWorktree, EnterWorktree refuses (and a hand-made worktree bypasses the guard entirely)
Environment
- Claude Code:
2.1.237 - Platform: macOS (Darwin 25.5.0), shell: zsh
- Session type: background job
- Layout: session cwd is a plain folder that is not a git repo; the git repo is nested one level below it
Summary
In a background session whose cwd is not a git repo, the write guard and EnterWorktree contradict each other, and there is no third option: the guard refuses every edit until the session isolates, and EnterWorktree refuses to isolate because cwd is not a repo. The session cannot edit a file in the nested repo at all.
Separately — and this is the part I think matters more — the same guard permits editing that same repo through a hand-made worktree, so the restriction is not actually enforcing what it appears to.
This is distinct from #78086 (there, cwd is a repo and git worktree list spuriously exits 1). Here EnterWorktree's refusal is correct by its own logic; the bug is that the guard demands a remedy which cannot exist in this layout.
Reproduction
- Create a non-repo directory with a git repo nested inside it:
````
~/projects/vault/ <- plain folder, NOT a git repo (in our case an Obsidian vault)
~/projects/vault/brain/ <- git repo
- Start a background session with cwd
~/projects/vault. - Attempt
Edit/Writeon~/projects/vault/brain/company/DECISIONS.md:
````
This background session hasn't isolated its changes yet. Call EnterWorktree first so
edits land in a worktree instead of the shared checkout, then retry this edit using
the worktree path. (To disable this guard for this repo, set "worktree":
{"bgIsolation": "none"} in .claude/settings.json.)
- Follow that instruction. Both modes fail:
EnterWorktree({name: "..."})→Cannot create a worktree: not in a git repository and no WorktreeCreate hooks are configured.EnterWorktree({path: "<vault>/brain/.claude/worktrees/x"})→Cannot enter an existing worktree: the current directory is not in a git repository.
Expected: isolation resolves against the repo that owns the file being written, so a nested repo is isolatable.
Actual: the guard demands isolation, the isolation tool refuses to provide it, and no edit is possible. Deadlock.
The suggested opt-out also cannot work here
The denial suggests "worktree": {"bgIsolation": "none"} in .claude/settings.json. We had already committed exactly that at brain/.claude/settings.json — but settings resolve from the session's launch cwd (the vault), not from the repo containing the target file, so the committed opt-out never loads. The escape hatch the message points at is unreachable in the same layout that creates the problem.
The soundness problem: the guard governs path shape, not risk
Two of our background sessions worked on this same repo within hours of each other:
- Session A — tried to edit
brain/company/DECISIONS.mdviaEdit. Hard-denied, as above. Still blocked; the file is its deliverable. - Session B — needed to edit source in another repo entirely.
EnterWorktree(path=…)refused with the same not-a-git-repository error, so it rangit worktree addby hand and edited through absolute paths into that worktree. The guard raised nothing. It committed and pushed successfully.
Same guard, same machine, same hour. The difference in outcome was not risk, reversibility, or review — only which path shape the guard recognised. A third session (mine), blocked from writing under its own job scratch directory, re-cloned its repo elsewhere on disk and edited freely there.
So in one day, three sessions stepped outside this control simply by working through a path it does not recognise, while the single session it actually stopped was the one writing a markdown note. If the guard's purpose is to prevent unreviewed edits to a shared checkout, it is currently not achieving that — and it is imposing a hard block on the least risky case.
Suggested direction
Key isolation to the target path, not the session's launch cwd:
- Resolve the enclosing git repo of the file being written (including repos nested under a non-git cwd) and isolate against that repo.
- Let
EnterWorktreetarget a repo other than the one at cwd — a sibling, or one nested below a non-git cwd. That alone fixes the deadlock. - Resolve
worktree.bgIsolationfrom the settings of the repo that owns the target file, so a committed per-repo opt-out is actually reachable. - If a session legitimately writes to several repos, isolation likely needs to be per-target rather than per-session.
(2) and (3) are individually sufficient to unblock the deadlock; (1) is what closes the hand-made-worktree hole.
Impact
Any layout where a repo lives below a non-repo directory — docs vaults, monorepo-adjacent notes, multi-repo workspaces opened at their parent — makes background sessions unable to write to that repo, with the suggested workaround also unreachable. Meanwhile the same restriction is trivially bypassed by anyone who creates a worktree by hand.