Skip to content

fix: allow api_key="" to bypass credential validation for local servers#3274

Open
SanskaarUndale21 wants to merge 2 commits into
openai:mainfrom
SanskaarUndale21:fix/api-key-empty-string-validation
Open

fix: allow api_key="" to bypass credential validation for local servers#3274
SanskaarUndale21 wants to merge 2 commits into
openai:mainfrom
SanskaarUndale21:fix/api-key-empty-string-validation

Conversation

@SanskaarUndale21
Copy link
Copy Markdown

@SanskaarUndale21 SanskaarUndale21 commented May 19, 2026

Fixes #3224

Summary

  • v2.34.0 changed the credential check from api_key is None to not self.api_key (truthiness), which rejects api_key="" as missing credentials
  • This broke local OpenAI-compatible servers (llama.cpp, llamafile, LM Studio, vLLM, etc.) that pass api_key="" because no auth is needed
  • Fix tracks _api_key_explicitly_provided before the env var fallback in both OpenAI.__init__() and AsyncOpenAI.__init__()

How it works

Capture whether the caller explicitly passed api_key before the env var fallback:

_api_key_explicitly_provided = False  # safe default for workload_identity path
# ...
else:
    _api_key_explicitly_provided = api_key is not None  # capture before env fallback
    if api_key is None:
        api_key = os.environ.get("OPENAI_API_KEY")

Then skip the error when the caller explicitly passed api_key="":

if (
    _enforce_credentials
    and not self.api_key
    and not _api_key_explicitly_provided  # allow explicit empty string
    and self._api_key_provider is None
    and workload_identity is None
    and self.admin_api_key is None
):

Behavior

Scenario Before fix After fix
api_key="" explicitly passed raises OpenAIError allowed
api_key=None, no env var raises OpenAIError raises OpenAIError
api_key=None, env var set works works
workload_identity set works works

Test plan

  • OpenAI(api_key="", base_url="http://localhost:8080/v1") no longer raises
  • AsyncOpenAI(api_key="", base_url="http://localhost:8080/v1") no longer raises
  • OpenAI() with no env var still raises OpenAIError

Fixes openai#3224 - v2.34.0 changed the credential check from an identity
check to a truthiness check, breaking api_key="" used by local
OpenAI-compatible servers (llama.cpp, LM Studio, vLLM, etc.).

Track _api_key_explicitly_provided before env var fallback so an
explicit empty string is treated as intentional and skips the error,
while omitting api_key entirely with no env var still raises.
@SanskaarUndale21 SanskaarUndale21 requested a review from a team as a code owner May 19, 2026 15:12
Copilot AI review requested due to automatic review settings May 19, 2026 15:12
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts credential enforcement in the core OpenAI client constructors to restore compatibility with OpenAI-compatible local servers that intentionally pass api_key="" (no auth required), which started failing after a truthiness-based credential check was introduced in v2.34.0.

Changes:

  • Track whether api_key was explicitly provided (pre–env var fallback) in OpenAI.__init__.
  • Apply the same tracking and updated enforcement logic in AsyncOpenAI.__init__.
  • Update the “missing credentials” guard to allow explicitly provided empty-string API keys.
Comments suppressed due to low confidence (2)

src/openai/_client.py:702

  • Same as the sync client: allowing api_key="" at init is not sufficient for local-server usage because requests will still fail header validation (_validate_headers) unless Authorization is explicitly omitted/provided. Consider carrying the “explicit empty api_key” signal through to request header validation for the async client as well.
        if (
            _enforce_credentials
            and not self.api_key
            and not _api_key_explicitly_provided
            and self._api_key_provider is None

src/openai/_client.py:193

  • Tests appear to cover the missing-credentials error when api_key=None (see tests/test_client.py::test_validate_headers), but there’s no assertion for the new behavior that api_key="" is allowed. Adding sync + async unit tests for api_key="" (with OPENAI_API_KEY/OPENAI_ADMIN_KEY unset) would prevent regressions in credential enforcement logic.
        if (
            _enforce_credentials
            and not self.api_key
            and not _api_key_explicitly_provided
            and self._api_key_provider is None

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/openai/_client.py
Comment on lines 189 to 193
if (
_enforce_credentials
and not self.api_key
and not _api_key_explicitly_provided
and self._api_key_provider is None
…alidation for api_key=""

Copilot flagged that bypassing the init-time credential check was incomplete --
_validate_headers still raised TypeError on every request when api_key="" because
_bearer_auth returns {} for falsy keys. Store the flag as an instance variable and
check it in _validate_headers for both OpenAI and AsyncOpenAI.
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.

AsyncOpenAI(api_key="") raises OpenAIError in v2.34.0, breaking OpenAI-compatible local servers

2 participants