[BUG] transcript_path in stop hook uses cwd hash instead of git-root hash when running in a git worktree
Problem
When Claude Code is opened with a git worktree as the working directory, the session JSONL is stored using the git root path, but transcript_path in stop hook payloads uses the literal cwd path. These produce different directory hashes, so transcript_path points to a file that does not exist.
Root Cause
Claude Code appears to use two different directory resolution strategies:
- Session JSONL storage: Uses the git repository root (e.g.,
/workspace) → hash-workspace→ stored at~/.claude/projects/-workspace/{session_id}.jsonl transcript_pathin hook payload: Uses the literal cwd (e.g.,/workspace/.claude/worktrees/branch-name) → hash-workspace--claude-worktrees-branch-name→~/.claude/projects/-workspace--claude-worktrees-branch-name/{session_id}.jsonl
The file at the transcript_path location does not exist. Any stop hook that attempts to read it gets NoSuchFileException / FileNotFoundError.
Reproduction Steps
- Open Claude Code inside a git worktree:
````
cd /path/to/repo/.claude/worktrees/my-branch
claude
- Configure a stop hook that reads
transcript_pathfrom the hook input JSON - End any conversation turn
- Stop hook crashes —
transcript_pathpoints to a non-existent file
Expected Behavior
transcript_path should point to the actual session JSONL file (i.e., use the same path resolution as session storage — the git repository root).
Actual Behavior
transcript_path points to ~/.claude/projects/-workspace--claude-worktrees-branch-name/{session_id}.jsonl which does not exist.
Evidence
# Session JSONL — EXISTS (git root hash)
~/.claude/projects/-workspace/b00a652b-66b6-4223-906f-4ccc3061aa89.jsonl
# transcript_path from hook payload — DOES NOT EXIST (cwd hash)
~/.claude/projects/-workspace--claude-worktrees-rewrite-test-prompts/b00a652b-66b6-4223-906f-4ccc3061aa89.jsonl
Environment variables at the time of hook invocation:
CLAUDE_PROJECT_DIR=/workspace(git root — correct)PWD=/workspace/.claude/worktrees/rewrite-test-prompts(cwd — used for transcript_path hash)
Environment
- Claude Code CLI
- Linux/WSL2
- Git worktree path:
/workspace/.claude/worktrees/rewrite-test-prompts - Git root:
/workspace
Workaround
Create a symlink from the cwd-derived path to the actual session file:
ln -s ~/.claude/projects/-workspace/{session_id}.jsonl ~/.claude/projects/-workspace--claude-worktrees-branch-name/{session_id}.jsonl
Or in hook code: construct the transcript path from CLAUDE_PROJECT_DIR + session_id rather than trusting transcript_path.
Related
- #34437: Worktrees should share the same project directory
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗