[BUG] `claude --resume "<title>"` matches no titles when the ~/.claude/projects dir case-mismatches cwd — only in repos with 2+ git worktrees
Summary
On a case-insensitive filesystem, claude --resume "<session title>" fails for every title in a project — reporting does not match any session title — when the project's directory under ~/.claude/projects/ differs in case from the slug of the current working directory. Resume by UUID keeps working, so the transcripts are provably fine.
The trigger is unexpected: the bug only appears when git worktree list returns more than one worktree. With a single worktree the same case mismatch is harmless.
This is a different mechanism from the same-symptom reports in #25032 (sessions-index.json staleness), #57203, #49128 and #46522 — none of those identify a case-sensitivity or worktree-count dependency, and this one reproduces deterministically.
Steps to reproduce
- On macOS (case-insensitive APFS), take a git repo at
~/Projects/app. - Register a second worktree so
git worktree listreturns 2+ entries:
git worktree add .claude/worktrees/scratch
- Make the transcript directory case-mismatch the canonical cwd. This happens by itself if you ever launched Claude Code from a differently-cased spelling of the path — a case-insensitive shell accepts
cd ~/projects/app— which creates~/.claude/projects/-Users-me-projects-app(lowercasep) and it persists forever after. To force it:
mv ~/.claude/projects/-Users-me-Projects-app ~/.claude/projects/tmp && mv ~/.claude/projects/tmp ~/.claude/projects/-Users-me-projects-app
- From
~/Projects/app, take the exact title of any session in that project and run:
claude --resume "<that exact title>" -p "hi"
Expected
The session resumes, as it does when given the same session's UUID.
Actual
Error: --resume requires a valid session ID or session title when used with --print.
Usage: claude -p --resume <session-id|title>. Provided value "<that exact title>"
is not a UUID and does not match any session title.
Every title in the project fails identically — custom titles set with /rename, auto-generated titles, and titles of sessions that are running right now. claude --resume <uuid> succeeds for the same session.
Confirmation of the cause
Renaming the directory to the matching case is sufficient and immediate — same command, no other change:
$ claude --resume "My session title" --fork-session -p "reply OK"
Error: ... does not match any session title
$ cd ~/.claude/projects && mv -- "-Users-me-projects-app" tmp && mv -- tmp "-Users-me-Projects-app"
$ claude --resume "My session title" --fork-session -p "reply OK"
OK
Reading the bundled CLI, the candidate-session list is built one of two ways depending on worktree count. With a single worktree the project path is joined directly, so the filesystem resolves the case and everything works. With more than one worktree it instead reads the contents of ~/.claude/projects/ and matches the returned directory names against the cwd slug by case-sensitive string prefix. A case-mismatched directory therefore never matches, the candidate list comes back empty, and the title matcher — which is otherwise fine — has nothing to search. Hence "no such title" for every possible input.
Suggested fix: compare those directory names case-insensitively on case-insensitive platforms, or normalize the slug when the directory is first created so the mismatch cannot arise.
Related, same underlying cause
~/.claude.json keys its projects map by literal path string, so both spellings accumulate as separate entries. The unused one is an empty stub, and if a session starts from the differently-cased cwd it lands there with no lastSessionId — which starves --continue as well. Worth normalizing in the same place.
Notes
- Silent and total: no warning, and because UUID resume still works it looks like the titles were never saved rather than like a lookup failure.
- Also observed: in
--printmode the title must match exactly (case-insensitively, but not as a substring), while the interactive picker accepts substrings. If that asymmetry is intentional it would help to say so in the error text.
Environment
- Claude Code 2.1.223 (Homebrew cask), CLI
- macOS 15 / Darwin 25.6.0, arm64, APFS (case-insensitive)