Desktop app session worktrees don't initialize git submodules (CLI --worktree does) — CLAUDE.md imports and project hooks silently broken

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 1 comment · opened Aug 2, 2026

Summary

Session worktrees created by the Claude desktop app are born without git submodules initialized, so @imports in CLAUDE.md that point into a submodule silently resolve to nothing and the session starts with partial instructions. The CLI path does it right: claude -p --worktree (v2.1.220) materializes submodules in the new worktree before context assembly, and the first session sees the imported content. The desktop app's worktree-creation path appears to be older or different.

Environment

  • Claude desktop app: 1.24012.9 (macOS)
  • Claude Code CLI on the same machine: 2.1.220
  • macOS 26.5.1 (Darwin 25.5.0), git 2.50.1 (Apple Git-155)

Setup

A repo whose agent instructions live in a pinned submodule:

  • .gitmodules declares submodule vvcore/
  • CLAUDE.md contains @vvcore/.../OPERACAO.md (+ other imports from the submodule)
  • .claude/settings.json project hooks (PreToolUse/PostToolUse) invoke scripts inside the submodule ($REPO/vvcore/bin/...), written fail-open

Observed (same machine, same repo, same day)

| Worktree creation path | Submodule in new worktree | Imported content in first session's context |
|---|---|---|
| Desktop app session worktree (.claude/worktrees/<name>) | empty | missing (agent had to notice and run git submodule update --init mid-session) |
| CLI claude -p --worktree <name> | populated automatically | present (verified: agent answered YES to a marker string that only exists in the submodule-imported doc) |
| plain git worktree add (control) | empty (expected git behavior) | — |

Also note: the repo has a post-checkout git hook installed (in .git/hooks) that runs git submodule update --init. It fires on manual git worktree add, but does not fire when the desktop app creates the session worktree, and there is no error surfaced anywhere — so the failure is completely silent.

Impact

  1. First session in a fresh desktop worktree runs with partial instructions (whatever CLAUDE.md imports from the submodule is silently absent). A second session in the same worktree is fine once something initialized the submodule.
  2. Worse: project hooks that call scripts inside the submodule (e.g., a git-command gate on PreToolUse, a secret scanner on PostToolUse) silently no-op in these sessions if written fail-open, since the target scripts don't exist yet. Security/compliance hooks being silently disabled is the sharp edge here.

Minimal repro

mkdir canon-src && cd canon-src && git init
echo "MARKER-CANON-42" > CANON.md && git add -A && git commit -m canon
cd .. && mkdir app && cd app && git init
printf '@vvcore/CANON.md\n' > CLAUDE.md
git -c protocol.file.allow=always submodule add ../canon-src vvcore
git add -A && git commit -m app

Then, in the desktop app, start a new session in a worktree for app and ask:

Answer with exactly one word, YES or NO: does the text MARKER-CANON-42 appear anywhere in your instructions/context?
  • Desktop worktree session → NO, and <worktree>/vvcore/ is empty.
  • Same question via claude -p --worktree testYES, and <worktree>/vvcore/CANON.md exists.

Expected

Desktop-created session worktrees should materialize submodules the same way the current CLI --worktree path does (init before CLAUDE.md import resolution), or at minimum surface a visible warning that the worktree is incomplete.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗