openai/openai-python · error · ValueError

The `default_query` and `set_default_query` arguments are mu

Error message

The `default_query` and `set_default_query` arguments are mutually exclusive

What it means

The query-string analogue of the headers conflict: `copy(default_query=...)` merges query params while `copy(set_default_query=...)` replaces them; supplying both is rejected with ValueError.

Source

Thrown at src/openai/_client.py:709

        timeout: float | Timeout | None | NotGiven = not_given,
        http_client: httpx2.Client | None = None,
        max_retries: int | NotGiven = not_given,
        default_headers: Mapping[str, str] | None = None,
        set_default_headers: Mapping[str, str] | None = None,
        default_query: Mapping[str, object] | None = None,
        set_default_query: Mapping[str, object] | None = None,
        _enforce_credentials: bool | None = None,
        _extra_kwargs: Mapping[str, Any] = {},
    ) -> Self:
        """
        Create a new client instance re-using the same options given to the current client with optional overriding.
        `data_residency` replaces the inherited HTTP and WebSocket endpoints, without changing this client.
        """
        if default_headers is not None and set_default_headers is not None:
            raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive")

        if default_query is not None and set_default_query is not None:
            raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive")

        provider_changed = not isinstance(provider, NotGiven) and provider is not self._provider
        inherited_organization = None if provider_changed else self.organization
        inherited_project = None if provider_changed else self.project

        headers: Mapping[str, str] = {} if provider_changed else self._custom_headers
        if (
            is_x509_workload_identity(workload_identity)
            and not is_x509_workload_identity(self.workload_identity)
            and self._ambient_authorizations
        ):
            headers = {
                name: value
                for name, value in headers.items()
                if name.lower() != "authorization" or value not in self._ambient_authorizations
            }
        if default_headers is not None:
            if any(name.lower() == "authorization" for name in default_headers):

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Use only `set_default_query` to fully control the query, or only `default_query` to add on top of inherited params
  2. Normalize kwargs in wrapper code so both never appear together

Example fix

# before
new = client.copy(default_query={'a': 1}, set_default_query={'b': 2})

# after
new = client.copy(set_default_query={'a': 1, 'b': 2})
Defensive patterns

Strategy: validation

Validate before calling

assert not (default_query is not None and set_default_query is not None), \
    'copy(): default_query XOR set_default_query'

Prevention

When it happens

Trigger: `client.copy(default_query={'api-version': 'x'}, set_default_query={'foo': 'bar'})`; generic client-derivation helpers forwarding both.

Common situations: Multi-tenant gateways adding per-tenant query params on top of defaults; refactors between merge and replace semantics.

Related errors


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