Resume picker shows no sessions when cwd is inside a git submodule
Summary
When cwd is inside a git submodule, claude --resume (and /resume) reports "No conversations found to resume" even when the project bucket for that path contains many sessions. Sessions are still being written to the correct bucket — the bug is in how the picker reads them.
Environment
- Claude Code:
2.1.132 - Platform: macOS (Darwin 25.3.0, arm64)
- Repo layout: parent repo with a git submodule at
packages/bundles(its.gitis a file pointing to<parent>/.git/modules/packages/bundles)
Reproduction
- Have a parent repo containing a git submodule at, e.g.,
packages/bundles. - From the parent repo root, start a Claude Code session, then
cd packages/bundles(or start a session there directly). Have a real conversation. Exit. cd packages/bundles && claude --resume
Expected: The picker lists sessions from the submodule's project bucket (~/.claude/projects/-...-langdock-packages-bundles/).
Actual: "No conversations found to resume." — even though ~/.claude/projects/-...-langdock-packages-bundles/ contains 100+ jsonl files (including ones written today).
Resuming from the parent repo root does show those bundles sessions (because the parent worktree path is a prefix of the bundles project path).
Root cause
The resume picker resolves the project path via git worktree list --porcelain (function gkH in the bundled CLI):
async function gkH(H) {
let { stdout: q } = await P8(C8(), ["worktree", "list", "--porcelain"], { cwd: H, ... });
let T = q.split("\n").filter($ => $.startsWith("worktree ")).map($ => $.slice(9).normalize("NFC"));
let A = T.find($ => H === $ || H.startsWith($ + path.sep));
...
}
For a submodule, git worktree list --porcelain returns the main worktree as the internal git dir, not the checkout path:
$ cd packages/bundles && git worktree list --porcelain
worktree /Users/me/Projects/langdock/.git/modules/packages/bundles
HEAD ...
branch refs/heads/...
The cwd is /Users/me/Projects/langdock/packages/bundles. None of the returned worktree paths equal it, and cwd.startsWith(worktreePath + sep) is false for every entry (the .git/modules/... path is not an ancestor of the checkout). So A is undefined, the worktree list passed to the session loader (MY6) doesn't include the actual checkout path, and the loader returns no sessions for that bucket.
filterResumableSessions (V1K) then sees an empty list and the picker reports "No conversations found to resume." Meanwhile sessions are still written to ~/.claude/projects/<cwd-encoded-as-slug>/... via a separate code path that uses cwd directly, so the bucket fills up but reads can never find it.
Suggested fix
When gkH finds no worktree entry that matches cwd (or when the matching entry is under .git/modules/), fall back to the cwd itself as the project path. Alternatively, detect submodules (e.g., parse .git as a file containing gitdir: ...) and substitute the real checkout dir for the .git/modules/... path returned by git worktree list.
Workarounds
- Resume from the parent repo root (sessions in subdirectories show up via the
startsWithcheck). - Name sessions upfront:
claude -n my-taskthenclaude --resume my-task— name-based resume bypasses the picker filter. - Resume by exact session ID:
claude --resume <uuid>also bypasses the picker.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗