openai/openai-python · error · ValueError

The `data_residency` and `base_url` arguments are mutually e

Error message

The `data_residency` and `base_url` arguments are mutually exclusive

What it means

resolve_data_residency (used by OpenAI(...) and client.copy()) raises ValueError when a named `data_residency` endpoint ('global'/'us'/'eu'/'ae') is combined with an explicit `base_url`. The named residency already determines the base URL, so an additional base_url would be contradictory.

Source

Thrown at src/openai/_data_residency.py:33

    "global": "https://api.openai.com/v1",
    "us": "https://us.api.openai.com/v1",
    "eu": "https://eu.api.openai.com/v1",
    "ae": "https://ae.api.openai.com/v1",
}


def resolve_data_residency(
    data_residency: DataResidency | None,
    base_url: str | httpx2.URL | None | NotGiven,
    *,
    provider: object | None = None,
    websocket_base_url: str | httpx2.URL | None = None,
) -> str | httpx2.URL | None:
    """Resolve a named endpoint before inherited or environment options are applied."""
    if data_residency is None:
        return None if isinstance(base_url, NotGiven) else base_url
    if not isinstance(base_url, NotGiven):
        raise ValueError("The `data_residency` and `base_url` arguments are mutually exclusive")
    if websocket_base_url is not None:
        raise ValueError("The `data_residency` and `websocket_base_url` arguments are mutually exclusive")
    if provider is not None:
        raise OpenAIError("The `data_residency` and `provider` arguments are mutually exclusive")
    if not isinstance(cast(object, data_residency), str) or data_residency not in _DATA_RESIDENCY_BASE_URLS:
        raise ValueError("Invalid `data_residency`; expected one of 'global', 'us', 'eu', or 'ae'")
    return _DATA_RESIDENCY_BASE_URLS[data_residency]

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Remove base_url and let data_residency select the regional endpoint.
  2. If you truly need the custom base_url, drop data_residency (ensure the custom URL already targets the desired residency region).
  3. Point the custom gateway at the residency endpoint and pass only base_url, or only data_residency.

Example fix

# before
client = OpenAI(data_residency="eu", base_url="https://api.openai.com/v1")

# after
client = OpenAI(data_residency="eu")
Defensive patterns

Strategy: validation

Validate before calling

def build_base(data_residency=None, base_url=None):
    if data_residency is not None and base_url is not None:
        raise ValueError("choose data_residency or base_url, not both")
    return data_residency or base_url

Prevention

When it happens

Trigger: OpenAI(data_residency="eu", base_url="https://custom.example.com/..."), or client.copy(data_residency="us", base_url=...) where base_url is any non-NotGiven value (including None passed explicitly as NotGiven check is bypassed when data_residency set and base_url given).

Common situations: Adding data residency to an existing deployment that already pinned a custom base_url for a gateway/proxy; configuring both in YAML/env-derived config dicts; regional-compliance rollout colliding with existing endpoint overrides.

Related errors


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