BerriAI/litellm · error · AzureOpenAIError
azure_client is not an instance of AzureOpenAI
Error message
azure_client is not an instance of AzureOpenAI
What it means
After get_azure_openai_client() builds the client for the sync text-completion path, LiteLLM asserts it is an instance of the OpenAI SDK's AzureOpenAI class; otherwise it raises AzureOpenAIError 500. The check catches a misconfigured client factory — e.g. the async class, a plain OpenAI client, or a mock — before calling .completions.with_raw_response.create.
Source
Thrown at litellm/llms/azure/completion/handler.py:154
"api_base": api_base,
"complete_input_dict": data,
},
)
if not isinstance(max_retries, int):
raise AzureOpenAIError(status_code=422, message="max retries must be an int")
# init AzureOpenAI Client
azure_client: Final = self.get_azure_openai_client(
api_key=api_key,
api_base=api_base,
api_version=api_version,
client=client,
litellm_params=litellm_params,
_is_async=False,
model=model,
)
if not isinstance(azure_client, AzureOpenAI):
raise AzureOpenAIError(
status_code=500,
message="azure_client is not an instance of AzureOpenAI",
)
raw_response: Final = azure_client.completions.with_raw_response.create(**data, timeout=timeout)
response: Final = raw_response.parse()
stringified_response: Final = response.model_dump()
## LOGGING
logging_obj.post_call(
input=prompt,
api_key=api_key,
original_response=stringified_response,
additional_args={
"headers": headers,
"api_version": api_version,
"api_base": api_base,
},
)View on GitHub (pinned to 6c2dcb801b)
Solutions
- Do not pass client= for the sync path; let LiteLLM construct the AzureOpenAI client from api_key/api_base/api_version.
- If you inject a client, ensure it is openai.types/AsyncAzureOpenAI counterpart per path: AzureOpenAI for completion/streaming, AsyncAzureOpenAI for acompletion/astreaming.
- Pin compatible openai SDK version matching your litellm version so isinstance checks see the same classes.
Example fix
# before async_client = AsyncAzureOpenAI(...) llm.completion(..., client=async_client) # sync path gets async client # after sync_client = AzureOpenAI(api_key=..., azure_endpoint=..., api_version=...) llm.completion(..., client=sync_client)
Defensive patterns
Strategy: type-guard
Validate before calling
from openai import AzureOpenAI
def validate_sync_client(client) -> None:
if client is not None and not isinstance(client, AzureOpenAI):
raise ConfigError(f"sync path needs AzureOpenAI, got {type(client).__name__}") Type guard
from openai import AzureOpenAI
from typing import TypeGuard
def is_sync_azure_client(c: object) -> TypeGuard[AzureOpenAI]:
return isinstance(c, AzureOpenAI) Try / catch
try:
resp = llm.completion(...)
except AzureOpenAIError as e:
if "not an instance of AzureOpenAI" in str(e):
raise ConfigError("Wrong client type injected for sync path") from e
raise Prevention
- Don't inject clients; pass api_key/api_base/api_version and let LiteLLM build them.
- Keep distinct sync/async client variables in shared code.
- Pin openai SDK version to the one your litellm release was tested against.
When it happens
Trigger: Passing a custom client= argument that is an AsyncAzureOpenAI or OpenAI instance into the sync path; get_azure_openai_client returning a plain OpenAI client because api_version/base resolution degenerated; test doubles replacing the client.
Common situations: Sharing one client object between sync and async code paths; DI frameworks injecting the wrong client type; upgrading the openai package where class identity moved between module aliases.
Related errors
- azure_client is not an instance of AsyncAzureOpenAI
- azure_client is not an instance of AzureOpenAI or OpenAI
- Unexpected string response from Azure: {response[:500]}
- AzureOpenAI client is not initialized. Make sure api_key is
- AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an en
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/0f20f982aca7ad62.
Report an issue: GitHub.