Nice ty
[Bug]: Forking a Claude thread fails after its project's workspace root changes#22796
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Create a project at
/work/appand run at least one turn in a Claude thread. - Move the repository to
/work/app/platformand point the project at it (t3_project_updatewith the newworkspaceRoot, which records aproject.meta-updatedevent). - Continue the thread. This still works.
- Fork the thread from any response and send a message in the fork.
Expected behavior
The fork starts from the parent's Claude session, the same way continuing the parent still does.
Actual behavior
The fork's turn fails to start with "Provider turn failed to start: Claude Agent SDK query failed." The server trace shows:
| 1 | ProviderAdapterForkThreadError: Failed to fork claudeAgent provider thread … |
| 2 | [cause]: ClaudeAgentSdkQueryRunnerError: Claude Agent SDK query failed. |
| 3 | [cause]: Error: Session <id> not found in project directory for /work/app/platform |
Claude files a transcript under the directory the session started in (~/.claude/projects/-work-app/<id>.jsonl). forkThread passes the thread's current cwd as dir (ClaudeAdapterV2.ts, forkOptions). With dir, the SDK only checks that directory's project folder and its git worktrees, so it never finds -work-app. Without dir, forkSession searches every project, which is how resume finds the same session.
The subagent launch lookup (subagentLaunchToolUseId, called with dir: runtimePolicy.cwd) has the same cwd pinning after a root change. Open PR #17596 is rewriting that call for custom Claude homes, so I left it out of the fix for this report.
Not a duplicate of #18260 (custom homePath, fixed in #18662): there the transcript was in a different Claude home. Here it is in the right home, but under an earlier project directory.
Impact
Major degradation or frequent failure
Version or commit
0.1.2-nightly.20261021.3457 (desktop, nightly)
Environment
macOS (Darwin 27), T3 Code desktop nightly, Claude Agent SDK 0.3.276, Claude provider on the default home.
Workaround
Symlink the transcript into the current directory's project folder: ln -s ~/.claude/projects/<old-slug>/<id>.jsonl ~/.claude/projects/<new-slug>/.
Confirming the same failure on 0.1.8 with a worktree-based variant of this repro.
Environment: T3 Code desktop (Beta), server 0.1.8; macOS client driving a remote Ubuntu environment over SSH; Claude Code CLI 2.1.321 through the claudeAgent provider (custom model). Not a custom Claude home.
Repro:
- A long-running Claude thread was created inside a git worktree of the project (
<repo>/worktrees/<name>), so its transcript lives under~/.claude/projects/<repo>--worktrees-<name>/<session>.jsonl. - The worktree was later removed. The thread record now has
worktreePath: nulland its provider session cwd is the repo root. Continuing the parent thread still works. - Fork the thread (
thread.forkfrom the latest assistant message) and send a message in the fork.
Actual behavior: thread.fork is accepted, and the fork's first turn fails within ~2 s:
| 1 | ProviderAdapterForkThreadError: Failed to fork claudeAgent provider thread ... |
| 2 | [cause]: ClaudeAgentSdkQueryRunnerError: Claude Agent SDK query failed. |
| 3 | [cause]: Error: Session <session-id> not found in project directory for <repo root> |
The outgoing SDK frame is session.fork with sessionId: <session-id>, options.dir: <repo root>, options.upToMessageId: <latest assistant cursor>. The transcript sits under the worktree slug, so the dir-pinned lookup cannot see it. The provider-turn.start effect retries 3 times (~150–300 ms apart), then the run is marked failed; a second message in the fork fails identically.
This looks like the same root cause described here (forkThread/forkOptions pinning dir to the thread's current cwd). Posting as a real-world confirmation that the transcript-under-a-previous-project-directory path also occurs when the source session was created in a worktree that T3 later removed, on 0.1.8. #22836 should cover it.