Skip to content

fix: treat empty-string ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN as absent#1726

Open
okxint wants to merge 1 commit into
anthropics:mainfrom
okxint:fix/empty-string-env-credential
Open

fix: treat empty-string ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN as absent#1726
okxint wants to merge 1 commit into
anthropics:mainfrom
okxint:fix/empty-string-env-credential

Conversation

@okxint

@okxint okxint commented Jul 2, 2026

Copy link
Copy Markdown

Summary

os.environ.get() returns "" for an env var that is present but empty — not None. When either ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN was set to an empty string (common in CI, containers, and in the Claude Code shell which exports both as empty), the SDK stored "" as the credential.

For ANTHROPIC_AUTH_TOKEN, _bearer_auth then built {"Authorization": "Bearer "} — a header with a trailing space and no token. h11 validates header values at write time and rejects b'Bearer ':

h11._util.LocalProtocolError: Illegal header value b'Bearer '

surfaced as anthropic.APIConnectionError on every request.

Fix

Apply or None to both env reads in Anthropic.__init__ and AsyncAnthropic.__init__:

# before
api_key = os.environ.get("ANTHROPIC_API_KEY")
auth_token = os.environ.get("ANTHROPIC_AUTH_TOKEN")

# after
api_key = os.environ.get("ANTHROPIC_API_KEY") or None
auth_token = os.environ.get("ANTHROPIC_AUTH_TOKEN") or None

This coerces empty strings to None so the SDK treats a present-but-empty var the same as unset.

Tests

Added test_empty_string_env_credentials_treated_as_absent to both TestAnthropic and TestAsyncAnthropic, verifying that api_key, auth_token, and auth_headers are all None / {} when the env vars are set to "".

Closes #1640

…bsent

os.environ.get() returns "" for a present-but-empty var, not None. When
the SDK stored an empty string as auth_token, _bearer_auth emitted an
"Authorization: Bearer " header (trailing space, no token). h11 rejects
that value at write time with LocalProtocolError, surfaced to callers as
APIConnectionError.

Apply `or None` to both env reads so an empty string is treated the same
as the variable being unset. Adds regression tests for both Anthropic and
AsyncAnthropic confirming that api_key, auth_token, and auth_headers are
all None / empty when the env vars are set to "".
@okxint okxint requested a review from a team as a code owner July 2, 2026 04:59
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.

Anthropic() emits a malformed Authorization: Bearer header when ANTHROPIC_AUTH_TOKEN is an empty string

1 participant