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

  1. Move auth/routing kwargs into the provider object, e.g. `OpenAI(provider=OpenAIProvider(api_key=..., base_url=...))`
  2. Or drop `provider` and keep top-level kwargs
  3. 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

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

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/9739da7a59a4d620. Report an issue: GitHub.