fix(server): API-key Claude instances no longer fail on subscriber API credits#29408

closed2
main
fix/issue-29393
opened9d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 19h ago

Problem

Since #28410, every Claude process T3 Code starts runs with CLAUDE_CODE_ENTRYPOINT=t3-code. Claude Code sends the entrypoint in its User-Agent (claude-cli/… (external, t3-code, …)). On an org that holds only Anthropic's API credits for subscribers, an API-key claudeAgent instance then fails every turn with billing_error "Credit balance is too low", and the thread reports "Claude gave up after repeated API errors." The same key works with the Agent SDK's own default entrypoint.

Reproduced on main (ac8dce0cc3): a dev server with a claudeAgent instance whose environment sets ANTHROPIC_API_KEY. Every turn sent (external, t3-code, agent-sdk/0.3.276) with x-api-key.

Change

mergeClaudeProcessEnvironment applies the t3-code default only when no non-empty ANTHROPIC_API_KEY is set in the host env, the instance env, or Claude's settings.json env. For API-key processes the variable is left unset, so the Agent SDK fills in sdk-ts and the bare CLI uses cli. An inherited host value such as claude-desktop is still dropped, as #28410 intended. An explicit CLAUDE_CODE_ENTRYPOINT in the instance env or settings.json still wins. Subscription logins keep t3-code. readClaudeSettingsEnv now also returns ANTHROPIC_API_KEY; the value is only checked for presence.

Scope and approval

Fixes pingdotgg/t3code#29393

Triaged via the automated issue flow.

Verification

  • vp test run apps/server/src/provider/Drivers/ClaudeHome.test.ts apps/server/src/provider/Drivers/ClaudeSkills.test.ts: 25/25 pass. The new test "leaves the entrypoint unset for API-key processes so Anthropic bills them" covers an API key from the instance env, the host env, and settings.json env. On main it fails with + "CLAUDE_CODE_ENTRYPOINT": "t3-code". The existing #28410 test, which keeps t3-code for subscription users and lets explicit overrides win, still passes.

  • vp run check:changed: format, lint, knip, typecheck and tests all pass.

  • Runtime transcript (the web dev server, T3CODE_DEV_SEED=0, a claudeAgent instance with a synthetic ANTHROPIC_API_KEY and ANTHROPIC_BASE_URL pointed at a local stand-in that logs request headers and answers t3-code requests like the reported credit-only rejection):

    1# main ac8dce0cc3 — Haiku 5.5, then Opus 5.5: thread shows "Credit balance is too low" / "Claude gave up after repeated API errors."
    215:20:28 POST /v1/messages claude-cli/2.1.304 (external, t3-code, agent-sdk/0.3.276) x-api-key=set
    315:22:23 POST /v1/messages claude-cli/2.1.304 (external, t3-code, agent-sdk/0.3.276) x-api-key=set
    4# fix 948fb7d649 — Opus 5.5, same prompt: turn completes with "ok"
    515:27:01 POST /v1/messages claude-cli/2.1.304 (external, sdk-ts, agent-sdk/0.3.276) x-api-key=set
  • Not checked: real Anthropic billing on a subscriber-credit-only org. No such account was available, so the billing outcome relies on the reporter's per-entrypoint results. Also not checked: Console /login keys stored by Claude Code itself and apiKeyHelper. Those send t3-code, as they did before this change.

Model: Claude Opus 5.5 (lead, tests, fix, review B) and GPT-6.1 Sol (review A) · Harness: Claude Code and Codex in T3 Code

🤖 Generated with Claude Code

Checks

22 successful · 18 skipped · 1 neutral
All checks passed
948fb7d

Added 2 commits

  • test(server): reproduce #29393 API-key Claude processes get the t3-code entrypoint6a0955e
  • fix(server): API-key Claude instances bill to subscriber credits again948fb7d
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — API-key Claude instances now use Claude's default entrypoint unless explicitly overridden, intended to restore subscriber API-credit eligibility. This changes existing product defaults and requires human acceptance of that behavior.

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 wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
CodexLive turn WebSocket decoded21.6 KiB21.6 KiB0 B (0.0%)24.4 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.3 KiB1.3 KiB0 B (0.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.9 KiB21.9 KiB0 B (0.0%)24.4 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: ac8dce0 · PR result: 948fb7d · 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 →

Walkthrough

Claude process environment construction now removes inherited entrypoint values and selects an entrypoint based on Claude settings and API-key presence. The settings environment type accepts ANTHROPIC_API_KEY, and tests cover API-key environment handling.

Changes: Claude API-key entrypoint handling

Layer / File(s)Summary
Build the Claude process environment
apps/server/src/provider/Drivers/ClaudeHome.ts, apps/server/src/provider/Drivers/ClaudeSkills.ts, apps/server/src/provider/Drivers/ClaudeHome.test.ts
SettingsEnv now accepts ANTHROPIC_API_KEY. Environment merging selects an entrypoint from settings or the merged environment, or defaults to t3-code only when neither contains an API key. Tests cover instance, host, and settings API keys.

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

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: t3dotgg

Merge Risk: External image Minimal · up to 948fb

API-key Claude processes configured through environment variables or settings no longer send the t3-code entrypoint, and subscription logins are unchanged. Keys supplied only through Console credentials or apiKeyHelper still send t3-code, as the PR notes. Billing on a credit-only organization was not tested, but nothing found here blocks merging.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title names the main change: API-key Claude instances no longer hit the subscriber-credit billing failure. The fix in the changeset does this by leaving CLAUDE_CODE_ENTRYPOINT unset for API-key pr…
Description checkPassedThe description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section states the failure, the reproduction on main, and the environment. The …
Linked Issues checkPassedIssue #29393 requires API-key Claude instances to run without the t3-code entrypoint so subscriber API credits can apply. mergeClaudeProcessEnvironment removes inherited CLAUDE_CODE_ENTRYPOINT a…
Out of Scope Changes checkPassedThe changes are limited to Claude process environment handling, settings decoding for ANTHROPIC_API_KEY, and regression coverage in the related driver test. These changes directly support issue #293…
Full details: Title check

Explanation

The title names the main change: API-key Claude instances no longer hit the subscriber-credit billing failure. The fix in the changeset does this by leaving CLAUDE_CODE_ENTRYPOINT unset for API-key processes in mergeClaudeProcessEnvironment, which is the change the title describes. The title is specific, follows the conventional commit form, and does not cover every detail, which is expected.

Full details: Description check

Explanation

The description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section states the failure, the reproduction on main, and the environment. The Change section explains the merge logic and the cases that keep or drop the entrypoint. Verification lists the focused test run, the check:changed result, a runtime transcript, and items not checked. The Scope and approval section links issue #29393 and says it was triaged through the automated issue flow. That gives a link to a triaged issue, but it does not include maintainer approval of the direction, which the template asks for. The author should add a maintainer approval comment or a discussion link that shows approval of the direction and scope, or explain why this focused bug fix qualifies without one. The description is otherwise mostly complete.

Full details: Linked Issues check

Explanation

Issue #29393 requires API-key Claude instances to run without the t3-code entrypoint so subscriber API credits can apply. mergeClaudeProcessEnvironment removes inherited CLAUDE_CODE_ENTRYPOINT and leaves it unset when a non-empty ANTHROPIC_API_KEY exists in the merged environment or Claude settings. It retains explicit settings or instance entrypoints and retains t3-code for subscription login flows. The regression test covers API keys from the instance, host, and settings environments. The reported test suite and local request transcript support the intended behavior.

Full details: Out of Scope Changes check

Explanation

The changes are limited to Claude process environment handling, settings decoding for ANTHROPIC_API_KEY, and regression coverage in the related driver test. These changes directly support issue #29393. No unrelated product behavior or unrelated files are changed.

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
CcoderabbitaiBotreviewed9d ago
Synced from GitHub
External image Additional comments: 1
apps/server/src/provider/Drivers/ClaudeHome.ts-83-83: 1

83-83: External image Major · Functional Correctness · Heavy lift

External image Unverified finding Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Account for API keys supplied outside environment variables.

Claude also supports apiKeyHelper and saved Console credentials. When either supplies the API key and ANTHROPIC_API_KEY is absent, this branch still selects t3-code, leaving those API-key instances subject to the reported credit failure. Detect the effective authentication source without executing credential helpers unnecessarily. (code.claude.com)


External image Review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between ac8dce0cc3abd8a337f2d806b5082a6834b9b81a and 948fb7d64979a30c592d9ed542ccefcbd3df2749.

External image Files selected for processing: 3
  • apps/server/src/provider/Drivers/ClaudeHome.test.ts
  • apps/server/src/provider/Drivers/ClaudeHome.ts
  • apps/server/src/provider/Drivers/ClaudeSkills.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

Closing as a duplicate of #29406, which covers the same subscriber-credit failure and includes real billing verification. Thanks, Julius, for the focused fix, and thanks to kyle944 for the earlier work.