microsoft/autogen · error · ValueError

azure_ad_token_provider must be a AzureTokenProvider to be c

Error message

azure_ad_token_provider must be a AzureTokenProvider to be component serialized

What it means

Thrown by AzureOpenAIChatCompletionClient._to_config during component serialization when azure_ad_token_provider is present in the raw config but is not an instance of autogen_ext.auth.azure.AzureTokenProvider. Serialization can only dump providers that implement the component API (dump_component), so arbitrary callables are rejected.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py:1727

            include_name_in_message=include_name_in_message,
        )

    def __getstate__(self) -> Dict[str, Any]:
        state = self.__dict__.copy()
        state["_client"] = None
        return state

    def __setstate__(self, state: Dict[str, Any]) -> None:
        self.__dict__.update(state)
        self._client = _azure_openai_client_from_config(state["_raw_config"])

    def _to_config(self) -> AzureOpenAIClientConfigurationConfigModel:
        from ...auth.azure import AzureTokenProvider

        copied_config = self._raw_config.copy()
        if "azure_ad_token_provider" in copied_config:
            if not isinstance(copied_config["azure_ad_token_provider"], AzureTokenProvider):
                raise ValueError("azure_ad_token_provider must be a AzureTokenProvider to be component serialized")

            copied_config["azure_ad_token_provider"] = (
                copied_config["azure_ad_token_provider"].dump_component().model_dump(exclude_none=True)
            )

        return AzureOpenAIClientConfigurationConfigModel(**copied_config)

    @classmethod
    def _from_config(cls, config: AzureOpenAIClientConfigurationConfigModel) -> Self:
        from ...auth.azure import AzureTokenProvider

        copied_config = config.model_copy().model_dump(exclude_none=True)

        # Handle api_key as SecretStr
        if "api_key" in copied_config and isinstance(config.api_key, SecretStr):
            copied_config["api_key"] = config.api_key.get_secret_value()

        if "azure_ad_token_provider" in copied_config:

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Wrap the callable in autogen_ext.auth.azure.AzureTokenProvider (implement/get or use the provided adapter) so it is serializable
  2. If serialization is not needed, keep the callable but avoid dump_component on this client
  3. Pass the token provider via a serializable custom AzureTokenProvider subclass whose config can round-trip

Example fix

# before
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
client = AzureOpenAIChatCompletionClient(
    ..., azure_ad_token_provider=get_bearer_token_provider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default")
)
client.dump_component()  # ValueError

# after
from autogen_ext.auth.azure import AzureTokenProvider
class MyTokenProvider(AzureTokenProvider):
    async def get_token(self):
        return get_bearer_token_provider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default")()
client = AzureOpenAIChatCompletionClient(..., azure_ad_token_provider=MyTokenProvider())
client.dump_component()  # ok
Defensive patterns

Strategy: type-guard

Validate before calling

from autogen_ext.auth.azure import AzureTokenProvider

provider = config.get("azure_ad_token_provider")
if provider is not None and not isinstance(provider, AzureTokenProvider):
    raise TypeError("wrap the callable in an AzureTokenProvider before constructing the client")

Type guard

def is_serializable_token_provider(provider) -> bool:
    from autogen_ext.auth.azure import AzureTokenProvider
    return provider is None or isinstance(provider, AzureTokenProvider)

Try / catch

try:
    component = client.dump_component()
except ValueError as e:
    if "azure_ad_token_provider" in str(e):
        # reconstruct with a serializable provider before persisting
        raise PersistenceError("re-wrap azure_ad_token_provider in AzureTokenProvider") from e
    raise

Prevention

When it happens

Trigger: Constructing the Azure client with azure_ad_token_provider=some_callable (any function, e.g. an async token getter passed directly) and then calling dump_component() / dump_component_json() on the client. Plain callables work at runtime but cannot be serialized.

Common situations: Following older examples that pass a raw DefaultAzureCredential token lambda; wrapping the client for checkpoint/persistence which triggers component serialization; copying auth code written before the AzureTokenProvider protocol existed.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/a6af2e002e9472c3. Report an issue: GitHub.