You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Empty OPENAI_BASE_URL prevents fallback to default API endpoint #2927
if base_url is None:
base_url = os.environ.get("OPENAI_BASE_URL")
if base_url is None:
base_url = f"https://api.openai.com/v1"
If the environment variable OPENAI_BASE_URL is defined but empty (e.g., OPENAI_BASE_URL=""), then os.environ.get("OPENAI_BASE_URL") returns an empty string. As a result:
base_url becomes ""
the second condition (if base_url is None) is never triggered
...uses is None for both checks, but os.environ.get() returns an empty string '' (not None) when the variable is set but empty. Empty string is falsy but not None, so the fallback never triggers.
The fix should be:
ifbase_urlisNone:
base_url=os.environ.get('OPENAI_BASE_URL') orNone# converts '' to Noneifbase_urlisNone:
base_url='https://api.openai.com/v1'
Workaround: Unset the environment variable entirely (unset OPENAI_BASE_URL or del os.environ['OPENAI_BASE_URL']) rather than setting it to an empty string. The bug only triggers when OPENAI_BASE_URL is defined but empty — if it's not set at all, os.environ.get() returns None and the fallback works correctly.
This is addressed by #2939 — when OPENAI_BASE_URL is set to an empty string, it now falls back to the default API endpoint instead of constructing an invalid URL.
The change only touches the environment fallback path: if OPENAI_BASE_URL is set to an empty string, the client now treats it the same as an unset value and falls back to the default API base URL. Explicit base_url arguments are left alone. I also added sync and async regressions for the empty-env case.
I can confirm this bug affects both sync and async clients (src/openai/_client.py) and applies to not just OPENAI_BASE_URL but also potentially other empty-string environment variables. The Bedrock provider (src/openai/providers/bedrock.py) already handles this correctly using a _normalize_optional_string() helper.
Affected Locations (4 places in _client.py):
Sync client - line 306: base_url = os.environ.get("OPENAI_BASE_URL")
Async client - line 1066: base_url = os.environ.get("OPENAI_BASE_URL")
The bug also affects self._base_url_was_default tracking (lines 307 and 1067):
Currently self._base_url_was_default = provider_runtime is None and base_url is None
This incorrectly marks "" as user-provided instead of falling through to default
Proposed Fix Code:
Add a shared helper function in src/openai/_utils/_utils.py (or at top of _client.py):
def_get_env(name: str) ->str|None:
"""Get an environment variable, treating empty strings as unset."""value=os.environ.get(name)
returnvalueifvalueelseNone
Then replace all occurrences in src/openai/_client.py:
Activity
fix: treat empty OPENAI_BASE_URL as unset
fix: treat empty OPENAI_BASE_URL env var as unset
xXMrNidaXx commentedon Mar 8, 2026
Good catch on the empty string edge case. The current logic:
...uses
is Nonefor both checks, butos.environ.get()returns an empty string''(notNone) when the variable is set but empty. Empty string is falsy but notNone, so the fallback never triggers.The fix should be:
Or equivalently:
Workaround: Unset the environment variable entirely (
unset OPENAI_BASE_URLordel os.environ['OPENAI_BASE_URL']) rather than setting it to an empty string. The bug only triggers whenOPENAI_BASE_URLis defined but empty — if it's not set at all,os.environ.get()returnsNoneand the fallback works correctly.giulio-leone commentedon Mar 9, 2026
This is addressed by #2939 — when
OPENAI_BASE_URLis set to an empty string, it now falls back to the default API endpoint instead of constructing an invalid URL.fix(client): treat empty OPENAI_BASE_URL as unset
mvanhorn commentedon Mar 10, 2026
I've submitted a fix for this in PR #2952. Uses
or Noneto normalize empty env var strings, applied to both sync and async constructors.fix: handle empty string in OPENAI_BASE_URL env var
passionworkeer commentedon Mar 14, 2026
This is a simple fix! I can submit a PR to handle the empty string case for OPENAI_BASE_URL.
fix(client): treat empty OPENAI_BASE_URL env var as unset
fix(client): treat empty OPENAI_BASE_URL as unset and fall back to de…
theamodhshetty commentedon Mar 19, 2026
Opened #2988 for this.
The change only touches the environment fallback path: if
OPENAI_BASE_URLis set to an empty string, the client now treats it the same as an unset value and falls back to the default API base URL. Explicitbase_urlarguments are left alone. I also added sync and async regressions for the empty-env case.fix(client): treat empty OPENAI_BASE_URL as unset, falling back to de…
fix: treat empty OPENAI_BASE_URL same as None for default fallback
fix: treat empty OPENAI_BASE_URL env var as unset to restore default …
fix: treat empty OPENAI_BASE_URL env var as unset, fall back to default
khalidsaidi commentedon Mar 25, 2026
A2ABench has an accepted answer for this imported thread.
ai villagefix: handle empty OPENAI_BASE_URL fallback to default endpoint (fixes o…
dajiaohuang commentedon Sep 25, 2026
Proposed Comprehensive Fix
I can confirm this bug affects both sync and async clients (
src/openai/_client.py) and applies to not justOPENAI_BASE_URLbut also potentially other empty-string environment variables. The Bedrock provider (src/openai/providers/bedrock.py) already handles this correctly using a_normalize_optional_string()helper.Affected Locations (4 places in
_client.py):base_url = os.environ.get("OPENAI_BASE_URL")base_url = os.environ.get("OPENAI_BASE_URL")self._base_url_was_defaulttracking (lines 307 and 1067):self._base_url_was_default = provider_runtime is None and base_url is None""as user-provided instead of falling through to defaultProposed Fix Code:
Add a shared helper function in
src/openai/_utils/_utils.py(or at top of_client.py):Then replace all occurrences in
src/openai/_client.py:Line 305-310 (sync client):
Line 1065-1070 (async client):
This pattern matches what already exists in
src/openai/providers/bedrock.py:30-35:A more thorough fix would also apply this normalization to:
OPENAI_API_KEY(line 253, 1013)OPENAI_ADMIN_KEY(line 263, 1023)OPENAI_ORG_ID(line 279, 1039)OPENAI_PROJECT_ID(line 283, 1043)OPENAI_WEBHOOK_SECRET(line 287, 1047)AZURE_OPENAI_ENDPOINT,AZURE_OPENAI_API_KEY, etc. inlib/azure.pyUsing
.strip()is also important for handling whitespace-only environment variable values which would also cause confusing failures.