openai/openai-python · error · OpenAIError
`provider` cannot be combined with top-level {formatted}. Mo
Error message
`provider` cannot be combined with top-level {formatted}. Move provider authentication and routing options into `{provider_name}(...)`. What it means
The sync `OpenAI(...)` constructor rejects mixing the `provider` parameter with top-level routing/auth options (`api_key`, `base_url`, `workload_identity`, etc.). Provider configuration must be self-contained via `OpenAIProvider(...)` (or the provider object) so credentials and endpoints come from one place.
Source
Thrown at src/openai/_client.py:221
data_residency, base_url, provider=provider, websocket_base_url=websocket_base_url
)
base_url = x509_data_residency_base_url(base_url, data_residency, workload_identity)
provider_runtime: _ProviderRuntime | None = None
if provider is not None:
provider_name = _provider_name(provider)
conflicts = [
name
for name, value in (
("api_key", api_key),
("admin_api_key", admin_api_key),
("workload_identity", workload_identity),
("base_url", base_url),
)
if value is not None
]
if conflicts:
formatted = ", ".join(f"`{name}`" for name in conflicts)
raise OpenAIError(
f"`provider` cannot be combined with top-level {formatted}. "
f"Move provider authentication and routing options into `{provider_name}(...)`."
)
provider_runtime = _configure_provider(provider)
self._provider = provider
self._provider_runtime = provider_runtime
if api_key is not None and api_key != WORKLOAD_IDENTITY_API_KEY_PLACEHOLDER and workload_identity is not None:
raise OpenAIError("The `api_key` and `workload_identity` arguments are mutually exclusive")
if is_x509_workload_identity(workload_identity):
workload_identity = workload_identity.copy()
self.workload_identity = workload_identity if provider_runtime is None else None
if provider_runtime is not None:
self.api_key = ""View on GitHub (pinned to 9917c6e28e)
Solutions
- Move auth/routing kwargs into the provider object, e.g. `OpenAI(provider=OpenAIProvider(api_key=..., base_url=...))`
- Or drop `provider` and keep top-level kwargs
- Check the conflict list in the message for exactly which kwargs to migrate
Example fix
# before client = OpenAI(provider=provider, api_key='sk-...', base_url='https://x') # after client = OpenAI(provider=OpenAIProvider(api_key='sk-...', base_url='https://x'))
Defensive patterns
Strategy: validation
Validate before calling
provider_kwargs = {'api_key': k, 'base_url': u}
if provider is not None and any(v is not None for v in provider_kwargs.values()):
provider = provider.replace_with(**provider_kwargs) # or build provider with these
provider_kwargs = {} Try / catch
try:
client = OpenAI(provider=provider, **kwargs)
except OpenAIError as e:
if 'cannot be combined with top-level' in str(e):
# move kwargs into the provider and retry
client = OpenAI(provider=provider_with(kwargs))
else:
raise Prevention
- Adopt one style: all auth/routing via provider, or all via top-level kwargs
- Parse the message's conflict list programmatically in config layers
When it happens
Trigger: `OpenAI(provider=..., api_key=...)`, `OpenAI(provider=..., base_url=...)`, or passing `workload_identity`/`admin_api_key` alongside `provider`; env vars are fine but explicit kwargs conflict.
Common situations: Adopting the provider API while keeping legacy kwargs; copy-pasting older constructor snippets onto new provider-based code.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The `api_key` and `workload_identity` arguments are mutually
- The `default_headers` and `set_default_headers` arguments ar
- The `default_query` and `set_default_query` arguments are mu
- The `data_residency` and `provider` arguments are mutually e
- Invalid provider. Providers must be created by an OpenAI pro
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/9739da7a59a4d620.
Report an issue: GitHub.