Skip to content

[v3.8.50] fix(auth): accept x-api-key without anthropic-version for claude-code user-agent (fixes #8655) - #8678

Merged
diegosouzapw merged 3 commits into
cheaper-inference:release/v3.8.50from
Dingding-leo:pr/fix-claude-code-x-api-key
Aug 6, 2026
Merged

diegosouzapw merged 3 commits into
cheaper-inference:release/v3.8.50from
Dingding-leo:pr/fix-claude-code-x-api-key

Conversation

@Dingding-leo

@Dingding-leo Dingding-leo commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #8655.

Root Cause

Claude Code and official Anthropic SDKs send HTTP requests containing x-api-key and standard User-Agent headers (e.g. claude-code/0.2.29 node/v20.18.0 darwin-x64 or anthropic-typescript/0.25.0), but omit the optional anthropic-version header.
Previously, extractApiKey checked if the request was an Anthropic client by verifying isClaudeClient = hasAnthropicVersionHeader || /claude-code|claude-cli|@anthropic-ai/i.test(userAgent). Requests with x-api-key were only honored if isClaudeClient evaluated to true. Because the regex did not match standard Anthropic SDK user agents (such as anthropic-typescript or anthropic-python) and required anthropic-version if the user agent didn't match @anthropic-ai, requests missing anthropic-version were rejected.

Fix

Updated isClaudeClient in src/sse/services/auth.ts to match /claude-code|claude-cli|anthropic/i against User-Agent. Any request carrying x-api-key with a Claude Code or Anthropic user agent (or anthropic-version header) is now properly recognized and authenticated.

Verification

  • Added unit tests in tests/unit/auth-extract-api-key.test.ts covering Claude Code and Anthropic SDK user agents without anthropic-version.
  • Passed node --import tsx/esm --test tests/unit/auth-extract-api-key.test.ts (28/28 tests passing).
  • Passed npx tsc --pretty false -p tsconfig.typecheck-core.json.

… user-agent (fixes #8655)

Claude Code sends requests with x-api-key and User-Agent headers, but omits anthropic-version. Previously, extractApiKey required anthropic-version to accept x-api-key fallback, rejecting valid Claude Code requests. By matching claude-code and anthropic SDK User-Agent strings, extractApiKey now accepts x-api-key for Claude Code clients.
Copilot AI review requested due to automatic review settings July 26, 2026 14:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@diegosouzapw diegosouzapw added hold-vps PR verde, merge aguardando validação live (release-drain) file-size-exceeded PR ejetada do merge-train — file-size frozen violation labels Jul 27, 2026
@diegosouzapw

Copy link
Copy Markdown
Collaborator

⏸️ Ejetada do merge-train v3.8.49 — file-size frozen violation

Esta PR foi ejetada do merge-train porque o diff faz src/sse/services/auth.ts (ou tests/unit/models-catalog-route.test.ts) ultrapassar o frozen baseline do file-size-cap (não pode crescer acima do baseline).

Motivo da ejeção

PR Arquivo Linhas atuais (após merge) Frozen Δ
#8756 src/sse/services/auth.ts 2504 2492 +12
#8678 src/sse/services/auth.ts 2504 2492 +12 (somado com #8756)
#8728 tests/unit/models-catalog-route.test.ts 1686 1608 +78

Por que o frozen é restritivo

A política do file-size ratchet no v3.8.49 congela o tamanho atual de arquivos server-side — não pode crescer até que v3.8.51 reaperte (issue #8768). Como o git stash é banido (Hard Rule #22a), o caminho é:

  1. Modularizar — extrair helpers em arquivos <name>Helpers.ts separados (técnica usada em outros PRs).
  2. Cherrypick isolado — para PRs com diff pequeno, fazer cherrypick apenas do subset que não toca os arquivos frozen.
  3. Reabrir após v3.8.51 — o re-tighten baixa cap para 850 (issue feat: re-tighten quality ratchets at v3.8.51 PREPARE-phase relax #8768), mas o frozen dos arquivos individuais ainda precisa ser reconsiderado.

Labels aplicadas

  • hold-vps
  • file-size-exceeded
  • (mantida needs-rebase se já estava)

Próximos passos

  • Comentário fixado para rastreabilidade.
  • Esta PR NÃO bloqueia o trem das outras 30 (que vai re-rodar em modo --fast na .113).

@diegosouzapw diegosouzapw added the deferred-v3.8.50 Adiada para o ciclo v3.8.50 (validacao VPS, refactor, ou escopo grande) label Jul 27, 2026
@diegosouzapw diegosouzapw changed the title fix(auth): accept x-api-key without anthropic-version for claude-code user-agent (fixes #8655) [v3.8.50] fix(auth): accept x-api-key without anthropic-version for claude-code user-agent (fixes #8655) Jul 27, 2026
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Heads-up: this PR is running against a stale base

release/v3.8.49 has moved 141 commits ahead of the base this PR was last built against, and several gate failures that were red on the older base have since been repaired on the branch itself:

Gate class Repaired by
No new ESLint warnings (exit 2 — orphaned suppressions, not a lint violation) #8706, #8831
Fast Quality Gates / check:file-size / Quality Ratchet #8585, #8767, plus the post-merge-train re-pins
Docs Gates (fast-path) (missing Polish API_REFERENCE) #8831
backoff-clamp + compressionDetailNormalizers unit tests #8706

I verified this on a clean checkout of the current tip (3b515d90b3): lint:json --max-warnings 0, check:file-size, check:docs-sync, error-classification.test.ts (24/24) and check-db-rules.test.ts (22/22) all pass with no changes.

Currently failing here:

  • Fast Quality Gates
  • Merge integrity (changelog + generated skills)

Please update the branch (the Update branch button, or rebase onto origin/release/v3.8.49) and let CI re-run. That should clear any failure caused by the stale base.

Note this is not a promise that every red disappears — a failure specific to the changes in this PR will survive the rebase, and Build (advisory) is advisory and does not block. Rebasing just removes the noise so what is left is actually yours.

No action was taken on this PR beyond this comment.

@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.49 to release/v3.8.50 July 28, 2026 18:41
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Re-homed to release/v3.8.50: v3.8.49 entered its release freeze, so the branch now belongs to the release captain and development continues on the next cycle. Nothing is wrong with this PR — it just needed a live base. No action needed from you; CI will re-run against the new base.

diegosouzapw and others added 2 commits August 4, 2026 20:49
Clean merge (no conflicts) — CHANGELOG.md diff vs release is empty (no base
bullets lost). src/sse/services/auth.ts grew past the frozen file-size ceiling
(2508 lines) once merged on top of the newer release tip (2503 lines); tighten
the isClaudeClient gate back to a 2-variable/1-line-if shape (same behavior,
same test coverage) so the file lands at 2506 lines, inside budget, instead of
widening the ratchet baseline.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Heads-up on the issue reference, not on the change itself: this PR body says it fixes #8655, but #8655 is the keyless OpenCode-Free (oc/*) tier returning 403, whose code path is open-sse/executors/opencode.ts / open-sse/services/opencodeQuotaFetcher.ts. This diff only touches src/sse/services/auth.ts (the isClaudeClient User-Agent matching) and its test — the two are unrelated, so it looks like a wrong issue number.

The change itself looks fine and stands on its own; could you update the reference to the issue it actually addresses (or drop the fixes line if there isn't one)? Left as-is, merging this would auto-close #8655 while the OpenCode 403 is still open.

For context: I re-triaged #8655 today and the reported root cause turned out to be different from what the reporter assumed — the quota endpoint is a red herring (it's dashboard-only and fails open); the real 403 comes from Cloudflare rejecting requests without CLI identity headers. That one needs a separate fix.

@diegosouzapw
diegosouzapw merged commit f843bac into cheaper-inference:release/v3.8.50 Aug 6, 2026
4 of 5 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…laude-code user-agent (fixes cheaper-inference#8655) (cheaper-inference#8678)

Validated in local merge-train T6 (ungrouped batch 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deferred-v3.8.50 Adiada para o ciclo v3.8.50 (validacao VPS, refactor, ou escopo grande) file-size-exceeded PR ejetada do merge-train — file-size frozen violation hold-vps PR verde, merge aguardando validação live (release-drain)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(providers): keyless OpenCode-Free (oc/*) tier returns 403 — quota scrape endpoint 404

3 participants