Skip to content

fix: normalize Anthropic header keys to lowercase in provider registry - #1527

Merged
diegosouzapw merged 1 commit into
diegosouzapw:release/v3.7.0from
prakersh:fix/duplicate-anthropic-version-header
Apr 24, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:release/v3.7.0from
prakersh:fix/duplicate-anthropic-version-header

Conversation

@prakersh

Copy link
Copy Markdown
Contributor

Summary

  • Normalize all Anthropic-specific header keys in providerRegistry.ts from PascalCase ("Anthropic-Version", "Anthropic-Beta", etc.) to lowercase ("anthropic-version", "anthropic-beta", etc.)
  • Update test assertions to match the new lowercase keys

Problem

The provider registry uses PascalCase header keys (e.g. "Anthropic-Version") while the Claude Code client path in base.ts (added in v3.6.9) uses lowercase keys ("anthropic-version"). Since JavaScript object keys are case-sensitive, both keys coexist in the headers object. When fetch() sends them, HTTP treats them as duplicates and concatenates the values:

anthropic-version: "2023-06-01, 2023-06-01"

This causes Anthropic's API to reject the request with a 400 error:

{"error":{"message":"[400]: anthropic-version: \"2023-06-01, 2023-06-01\" is not a valid version","type":"invalid_request_error","code":"bad_request"}}

Root cause

Two independent code paths setting the same HTTP header with different JS key casing:

  1. providerRegistry.ts (v1.0.0) — "Anthropic-Version": ANTHROPIC_VERSION_HEADER (PascalCase)
  2. base.ts ccHeaders (v3.6.9) — "anthropic-version": "2023-06-01" (lowercase)

Test plan

  • t20-t22-provider-headers.test.ts — passes with lowercase assertions
  • search-provider-validation.test.ts — passes with lowercase assertion
  • Full test suite (3238 tests) — all pass

The provider registry used PascalCase header keys (e.g. "Anthropic-Version")
while the Claude Code client path in base.ts sets lowercase keys
("anthropic-version"). Since JS object keys are case-sensitive, both keys
coexist in the headers object. When fetch() sends them, HTTP treats them
as duplicates and concatenates the values ("2023-06-01, 2023-06-01"),
causing Anthropic's API to reject the request with a 400 error.

Normalize all Anthropic-specific header keys to lowercase to match the
convention used in executors and the upstream API.
@prakersh
prakersh requested a review from diegosouzapw as a code owner April 23, 2026 07:21

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request normalizes several HTTP header keys to lowercase across various provider configurations in providerRegistry.ts and updates the corresponding unit tests. This change affects headers such as anthropic-version, anthropic-beta, and x-app. Feedback suggests further lowercasing remaining headers like User-Agent and X-Stainless-* to maintain consistency and prevent potential duplicate header issues during fetch calls.

"anthropic-dangerous-direct-browser-access": "true",
"User-Agent": CLAUDE_CLI_USER_AGENT,
"X-App": "cli",
"x-app": "cli",

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.

medium

The normalization of x-app to lowercase is consistent with the Anthropic headers, but the X-Stainless-* headers (lines 281-289) and the User-Agent header (line 279) remain in PascalCase. Since JavaScript object keys are case-sensitive, any other code path setting these headers in lowercase will cause fetch() to send duplicate headers (concatenated values), which is the root cause of the issue described in this PR. Consider lowercasing all header keys in this block for consistency, especially since other providers like github already use lowercase keys (e.g., user-agent).

@diegosouzapw
diegosouzapw changed the base branch from main to release/v3.7.0 April 23, 2026 11:09
@diegosouzapw
diegosouzapw merged commit 1b84c04 into diegosouzapw:release/v3.7.0 Apr 24, 2026
2 checks passed
@diegosouzapw diegosouzapw mentioned this pull request Apr 25, 2026
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
diegosouzapw#1527)

The provider registry used PascalCase header keys (e.g. "Anthropic-Version")
while the Claude Code client path in base.ts sets lowercase keys
("anthropic-version"). Since JS object keys are case-sensitive, both keys
coexist in the headers object. When fetch() sends them, HTTP treats them
as duplicates and concatenates the values ("2023-06-01, 2023-06-01"),
causing Anthropic's API to reject the request with a 400 error.

Normalize all Anthropic-specific header keys to lowercase to match the
convention used in executors and the upstream API.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
diegosouzapw#1527)

The provider registry used PascalCase header keys (e.g. "Anthropic-Version")
while the Claude Code client path in base.ts sets lowercase keys
("anthropic-version"). Since JS object keys are case-sensitive, both keys
coexist in the headers object. When fetch() sends them, HTTP treats them
as duplicates and concatenates the values ("2023-06-01, 2023-06-01"),
causing Anthropic's API to reject the request with a 400 error.

Normalize all Anthropic-specific header keys to lowercase to match the
convention used in executors and the upstream API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants