fix(server): Claude no longer shows unavailable when its health check can't run in $HOME#19320

merged1
main
t3/fix-claude-probe-cwd
opened29d agobyTtheo
View on GitHubTwo-way sync enabledPR last imported 23d ago

Fixes #2867.

Packaged desktop builds start the server with cwd = $HOME. The Claude --version health check inherited that cwd, and the capability probe used it. Some claude wrappers (containers, sandboxes, governance shims) refuse to run outside a project, so Claude showed as unavailable and the user never reached a session.

Fix

The Claude driver now runs its instance-level probes in the server's stateDir. This is T3's own data directory. It is never a project, and server startup creates it. The change applies to the capability probe, its cache key, and the status check. runClaudeCommand now takes an optional cwd.

Session spawns and per-thread workspace probes (snapshotForCwd) still use the thread's directory. They are not changed.

Proof

I started a real server from a fake $HOME, with a claude shim on PATH that logs its cwd and refuses to run in $HOME:

Where the spawns ranClaude status
main--version in $HOMEerror: installed but failed to run
main, shim refusal off--version and SDK probe in $HOMEready
this PRboth in <base-dir>/userdataready, authenticated

A new test in ProviderInstanceRegistry.test.ts uses the mock CLI with an opt-in guard that refuses to run outside one directory. Without the fix it fails with error. With only the --version half it fails with warning. It passes with the full fix.

vp test run on ProviderInstanceRegistry, ProviderRegistry, and ClaudeCapabilitiesProbe tests: 77 passed. Server typecheck and lint on the changed files are clean.

Diagnosis credit: #19174, which found the root cause. This PR is a separate implementation.

Reviewed with sol-loop: 1 round with GPT-6.1-Sol.

Model and harness: Claude Opus 5.5 in Claude Code via T3 Code.

πŸ€– Generated with Claude Code

Checks

26 successful Β· 10 skipped
All checks passed
8f42bc6

Added 1 commit

  • fix(server): Claude health check no longer runs in the server's home cwd8f42bc6
Synced from GitHub

Approvability

Verdict: Approved at 8f42bc6

Macroscope's review found this PR approvable β€” This is a focused server bug fix that moves only instance-level Claude probes to the existing state directory, while preserving project-scoped workspace and session execution. A live regression test covers the packaged-desktop cwd scenario, and no product defaults or static-analysis settings are changed.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

βœ… Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire4.9 KiB5.0 KiB+23 B (+0.5%)6.8 KiBβœ…
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiBβœ…
CodexLive turn WebSocket wire1.2 KiB1.2 KiB+23 B (+1.9%)2.0 KiBβœ…
CodexLive turn WebSocket decoded20.8 KiB20.9 KiB+41 B (+0.2%)29.3 KiBβœ…
CodexLive turn messages12+1 (+100.0%)8βœ…
ClaudeTotal thread wire5.0 KiB5.0 KiBβˆ’7 B (βˆ’0.1%)6.8 KiBβœ…
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiBβœ…
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiBβˆ’7 B (βˆ’0.6%)2.0 KiBβœ…
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiBβœ…
ClaudeLive turn messages220 (0.0%)8βœ…

Baseline: 614b432 Β· PR result: 8f42bc6 Β· Source CI: success

Scenario and decoded snapshot size

10 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.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Review in Change Stack β†’

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 25283be5-a5bf-42f1-82cf-2b7be7cff085
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 614b432a79b0acae38c27c00b1e4eece223ecfe4 and 8f42bc660d06a67527682f67c8564cb98bd115c4.

πŸ“’ Files selected for processing: 4
  • apps/server/src/provider/ClaudeProvider.ts
  • apps/server/src/provider/Drivers/ClaudeDriver.ts
  • apps/server/src/provider/ProviderInstanceRegistry.test.ts
  • apps/server/src/provider/testing/ProviderInstanceRegistryLive.fixture.mjs

Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.

πŸ“ Walkthrough

Claude instance-level capability probes and provider-status checks now run from the server state directory. Claude command execution accepts an explicit working directory. Workspace snapshot probes continue to use the thread working directory.

Changes: Claude probe working directory

Layer / File(s)Summary
Explicit working directory for Claude probes
apps/server/src/provider/ClaudeProvider.ts, apps/server/src/provider/Drivers/ClaudeDriver.ts, apps/server/src/provider/ProviderInstanceRegistry.test.ts, apps/server/src/provider/testing/ProviderInstanceRegistryLive.fixture.mjs
runClaudeCommand accepts and uses an optional cwd, which the provider-status version check now supplies. Instance-level probes, capability-cache keys, and status checks use stateDir; workspace snapshot probes retain the thread cwd. The fixture can reject an unexpected working directory, and a live test checks readiness, version, and authentication.

Priority: βž– Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix Β· Severity of issue fixed: Medium

Suggested reviewers: juliusmarminge

Merge Risk: βšͺ Minimal Β· up to 8f42b

Claude’s instance-level probes now use the server state directory, while workspace probes retain their thread directory. No merge-blocking issue is established; the change appears ready for normal checks.

Pre-merge checks: Passed 4
Passed Passed checks: 4 passed
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the primary fix: Claude no longer reports unavailable when health checks inherit an unsuitable $HOME working directory.
Description checkPassedThe description explains the problem, affected behavior, implementation scope, issue reference, verification steps, observed results, and test coverage. It uses "Fix" and "Proof" headings instead of t…
Linked Issues checkPassedIssue #2867 requires Claude auxiliary probes to use an explicit scoped working directory. ClaudeDriver.create now uses stateDir for the capability probe, capability cache key, and provider status …
Out of Scope Changes checkPassedThe changed driver code, command cwd support, registry test, and opt-in fixture guard all directly verify or implement issue #2867. The test and fixture changes are supporting automated coverage. No u…
✨ Finishing Touches
πŸ“ Generate docstrings
  • Commit to this branch
  • Create a new PR
πŸ§ͺ Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix Β· Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.