Repository navigation
fix(server): Claude sessions survive slow SessionStart hooks - #23202
juliusmarminge wants to merge 8 commits into
Conversation
…ude open Tests reproduce issue 23151: a Claude Code SessionStart hook that runs past 90 s makes ClaudeAgentSdkQueryRunner.open fail with "Claude Code did not answer the MCP server registration." Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude Code reads mcp_set_servers only after its SessionStart hooks finish. A hook can run up to the CLI's default 10 minute hook timeout, for example a cold worktree setup script, so the 90 s registration deadline failed the open while the CLI was healthy. The deadline now covers that hook budget plus the per-server connect time. The SDK still rejects the request if the CLI exits, and interrupting the open still closes the query. Fixes #23151 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — Claude sessions with MCP servers now allow 11.5 minutes rather than 90 seconds for registration, accommodating slow SessionStart hooks. This changes the default startup deadline and can extend the wait before a stalled registration fails. No code changes detected at You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
…ted pipes tsc-rs fails the server typecheck on effect(multipleEffectProvide) when one pipe chains two Effect.provide calls. Match the neighbouring fork test's shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The new regression test triggered Effect diagnostic TS377033 ( The longer deadline's tradeoff remains for maintainer approval: an unresponsive Claude process can hold an effect-worker slot for up to 690 seconds. No automatic landing is enabled. |
|
CI on 4ef439b has 12 failed checks: Build and Typecheck, Lint, Test, all eight server shards, and Check. Cafe provides conclusions and timestamps, but no failure output or annotations; its job-log endpoint rejects the GitHub check IDs. No current failure cause is established. Several other checks were skipped, including Test Web and Rust. Diagnosis needs the failed step, first error, and exit code from the CI run, starting with Lint, Build, and Server 1. No further code change was made. |
Resolve the query runner test conflict. Main's resumed-session retry tests now advance the clock by the exported registration deadline instead of a literal 90 seconds, and the slow SessionStart regression uses the shared real query runner with a fresh session ID, the case the retry never covers. AI-assisted; verified with the tests and tools listed above.
EvidenceConfigure a startup SessionStart command hook with timeout 600 and a first-run setup script that sleeps 105 seconds. Create a fresh linked-worktree Claude thread and send Environment on both sides: real web app and Claude provider, separate fresh databases, Chromium 1280×800, light theme, synthetic data. Chat captures exclude private metadata. Videos begin approximately 28 seconds into startup.
Reproduction driver · Persisted timing transcript AI-assisted; verified with the tests and tools listed above. Not shown:
|
96d6890 to
da798c0
Compare
|
The automated pipeline stopped on this pull request and will not merge it: someone else pushed to fix/issue-23151 (head is now da798c0); the pipeline does not build on commits it did not review It stays open for a person to finish or close. |
|
Note 🤖 Claude Fable 5.2 responding on behalf of Theo #30166 merged as What changed on Measured on the merge commit with the real Claude CLI (2.1.322) and Agent SDK 0.3.321: a What is left: a hook that runs for more than 5 minutes. This PR allows 690 seconds, and My judgment: this PR is superseded unless hooks longer than 5 minutes need support. I did not close it. |


Problem
A Claude turn in a new worktree fails while a legitimate SessionStart setup hook is still running: T3 gives MCP registration 90 seconds, but Claude does not answer that request until the hook completes. In the Linux web dev app with Claude Code 2.1.303, a cold-worktree-only 105-second hook reproduced the failure at 90.2 seconds; the same fixture worked directly in Claude and from its main checkout.
Change
Increase the Claude MCP registration deadline to 690 seconds, allowing the default 600-second hook timeout plus server connection time and slack. Add one regression test that completes registration after 105 seconds. The deadline remains bounded; an unresponsive CLI can now occupy an effect-worker slot for up to 11.5 minutes instead of 1.5 minutes. Hooks explicitly configured beyond this allowance can still time out.
Scope and approval
Fixes https://git.cafe/pingdotgg/t3code/pulls/23151
Triaged bug via the automated issue flow; GitCafe mirror #23155. This fixes the reproduced startup failure in the existing Claude adapter. Both initial isolated reviewers returned MERGE. The subsequent GPT review and Macroscope require human approval for the timing policy: an unresponsive CLI may occupy one of four effect-worker slots for longer. That approval remains pending. No client rendering or tool capabilities change.
Verification
Merged main into 52c7dcd. Resolved the timeout comment conflict while preserving the 690-second deadline and single regression test. Focused query-runner tests pass 4/4; scoped lint has no errors and one pre-existing unused
layerwarning. Formatting and PR-scoped diff checks pass. CI on this head has failed Lint and the aggregate Check. Both PR files pass targeted lint (also with CI=true), formatting and whitespace checks. The Lint job also runs Knip, generated-code checks and vp check; the failing substep is unknown without failed-step logs. No speculative code change was made; the preceding ff91e40 passed CI. Human timing-policy approval remains pending.Red proof: unchanged regression test fails on main plus the test, with “Claude Code did not answer the MCP server registration.” Failing output.
Green:
vp test run apps/server/src/orchestration-v2/Adapters/ClaudeAgentSdkQueryRunner.test.ts: 3/3 passed, including after merging current main into 13b0993.Follow-up 4ef439b nests the regression test’s layer provisioning to avoid Effect diagnostic TS377033 (
multipleEffectProvide). A minimal compiler fixture reproduces exit 2 before and exit 0 after; the focused test file still passes 3/3. CI failed on that earlier head without accessible failed-step diagnostics; the preceding merged head passed CI; CI is pending after the latest main merge. Production code is unchanged from the runtime-tested fix.Targeted lint passed with one pre-existing unused
layerwarning;git diff --checkpassed. Scoped server typecheck was stopped after overloading the VM and has no result.Server-only proof matrix is empty: no render paths changed. Runtime captures below were made on b5a226e and 7b67539. The production timeout change remains identical on the latest merged head; the regression test has only provisioning and import adjustments. Focused tests passed again on the merged head.
okBefore:
After:
Before recording · After recording. These are supplemental illustrations; the runtime transcript and regression test are the server proof. Chromium headless, Linux x64, 1280×800, light theme. The before recording begins partway through the wait; the after recording shows the whole attempt. No rendering changes are claimed.
Proof index and runtime transcript · Empty render matrix.
Unverified: reporter’s macOS desktop surface, native Windows and mobile; head controls, live-query reuse, the exact 690-second timeout/cleanup boundary, and remote/relay/tunnel execution. Reproduction used isolated empty development state because the real-data snapshot had incompatible migration names. Executing revisions are corroborated by reflog chronology and runtime traces, without a contemporaneous process-to-full-SHA attestation. The proof auditor used local artifact counterparts after public downloads returned HTTP 403. A first after attempt was interrupted by a dev-server restart and is excluded from the success claim.
Implemented with Claude Opus 5.5 through Claude Agent SDK; tests with Claude Opus 5.5; reviewed with GPT-6.1-Sol through Codex and Claude Opus 5.5 through Claude Agent SDK. Triage and evidence coordinated with GPT-6.1-Sol through Codex in T3 Code.