pingdotgg / pingdotgg/t3code

[Bug]: Provider probe runs with the server's cwd, so $HOME/.claude/settings.json is loaded as project settings and breaks CLAUDE_CONFIG_DIR isolation

Open
#8,818 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

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

Setup: two Claude provider instances with separate CLAUDE_CONFIG_DIR paths, per docs/user/providers-claude.md:

  • default ~/.claude = managed Bedrock install (IT-installed settings.json with CLAUDE_CODE_USE_BEDROCK=1, awsAuthRefresh, otelHeadersHelper)
  • ~/Developer/XXFAST/.claude = personal Max OAuth login
  1. Log the second config dir in with a Max account. CLAUDE_CONFIG_DIR=~/Developer/XXFAST/.claude claude auth status shows loggedIn: true, subscriptionType: max, apiProvider: firstParty.
  2. Point a Claude provider at that config dir in T3 settings.
  3. Let the periodic provider status check run a few times.
Expected behavior

The provider shows Authenticated · Claude Max with the account email, consistently. CLAUDE_CONFIG_DIR isolation should hold for the probe.

Actual behavior

The personal provider shows Authenticated · Amazon Bedrock, and every few minutes flaps to Could not verify Claude authentication status from initialization result. (which disables the model selector) until a restart or manual refresh.

Root cause

probeClaudeCapabilities runs with cwd from ServerConfig (ClaudeDriver.ts: const { cwd } = yield* ServerConfig). On the macOS desktop app the server's cwd is the user's home directory (verified with lsof -a -p <pid> -d cwd).

Claude Code loads <cwd>/.claude/settings.json as project settings. With cwd = $HOME, that file is ~/.claude/settings.json, the managed Bedrock config. Project settings apply on top of CLAUDE_CONFIG_DIR, so the probe of the personal instance:

  1. auths as Bedrock (CLAUDE_CODE_USE_BEDROCK=1 wins over the OAuth login in the isolated config dir), hence the wrong Amazon Bedrock label, and
  2. inherits the managed install's startup cost: otelHeadersHelper timing out (~10s) + awsAuthRefresh credential process (~6s per call). Init lands at ~25s, racing CAPABILITIES_PROBE_TIMEOUT_MS = 25_000 exactly. Under the wire you get the mislabeled "Authenticated", over it you get "Could not verify". Server traces show checkClaudeProviderStatus spans at 25,034ms.

Measured with a standalone repro of the probe (same SDK, same buildClaudeCapabilitiesProbeQueryOptions):

cwd result time
inside the project tree Claude Max · firstParty, correct email 0.85s
$HOME apiProvider: bedrock or 25s timeout ~25s

Repro script (node probe.mjs <configDir> <cwd>):

import { query } from "@anthropic-ai/claude-agent-sdk";

const abort = new AbortController();
async function* emptyPrompt() {
  await new Promise((resolve) => abort.signal.addEventListener("abort", resolve));
}
const q = query({
  prompt: emptyPrompt(),
  options: {
    persistSession: false,
    abortController: abort,
    settingSources: ["user", "project", "local"],
    settings: JSON.stringify({ disableAllHooks: true }),
    allowedTools: [],
    mcpServers: {},
    strictMcpConfig: true,
    env: { ...process.env, CLAUDE_CONFIG_DIR: process.argv[2], ENABLE_CLAUDEAI_MCP_SERVERS: "false" },
    cwd: process.argv[3],
    stderr: () => {},
  },
});
const t = setTimeout(() => { console.log("TIMEOUT 25s"); abort.abort(); process.exit(2); }, 25_000);
const init = await q.initializationResult();
clearTimeout(t);
console.log(JSON.stringify(init.account ?? null));
abort.abort();
process.exit(0);
Suggested fix

Run the capability probe with a neutral cwd (the resolved config dir, or os.tmpdir()) instead of the server's cwd, so <cwd>/.claude/settings.json can't leak another environment's auth into an isolated instance. The claude auth status fallback proposed in #4928 would also make the flapping cheaper to avoid (that command returns in ~1s against the same config dirs).

Impact

Major degradation or frequent failure

Version or commit

T3 Code 0.0.36 (desktop, macOS)

Environment

macOS (Darwin 25.4.0), Claude Code 2.1.251 (homebrew cask), Max OAuth in the isolated config dir, managed Bedrock install in default ~/.claude.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in ClaudeDriver.ts at probeClaudeCapabilities and trace how ServerConfig supplies cwd to buildClaudeCapabilitiesProbeQueryOptions. Reproduce the probe with separate CLAUDE_CONFIG_DIR and cwd values using the issue's standalone script. Done means project settings from the server's cwd no longer affect an isolated provider, while authentication and status checks remain reliable.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.