pola-rs/polars · error · ValueError

the provided `credential` object {credential!r} does not hav

Error message

the provided `credential` object {credential!r} does not have a `get_token()` method.

What it means

CredentialProviderAzure accepts an optional user-supplied `credential` object (typically from azure.identity). The constructor needs exactly one thing from it - a get_token() method (py-polars/src/polars/io/cloud/credential_provider/_providers.py:373-380); any object without that attribute raises ValueError immediately, with the repr of the offending object embedded in the message.

Source

Thrown at py-polars/src/polars/io/cloud/credential_provider/_providers.py:379

        msg = "`CredentialProviderAzure` functionality is considered unstable"
        issue_unstable_warning(msg)

        self.account_name = _storage_account
        self.scopes = (
            scopes if scopes is not None else ["https://storage.azure.com/.default"]
        )
        self.tenant_id = tenant_id
        self.credential = credential

        if credential is not None:
            # If the user passes a credential class, we just need to ensure it
            # has a `get_token()` method.
            if not hasattr(credential, "get_token"):
                msg = (
                    f"the provided `credential` object {credential!r} does "
                    "not have a `get_token()` method."
                )
                raise ValueError(msg)

        # We don't need the module if we are permitted and able to retrieve the
        # account key from the Azure CLI.
        elif self._try_get_azure_storage_account_credential_if_permitted() is None:
            self._ensure_module_availability()

        if verbose():
            eprint(
                "[CredentialProviderAzure]: "
                f"{self.account_name = } "
                f"{self.tenant_id = } "
                f"{self.scopes = } "
            )

        super().__init__()

    def retrieve_credentials_impl(self) -> CredentialProviderFunctionReturn:
        """Fetch the credentials."""

View on GitHub (pinned to df599052da)

Solutions

  1. Pass a real azure.identity credential (ClientSecretCredential, DefaultAzureCredential, ...) - all expose get_token
  2. If you meant an account key, pass it via storage_options (account_key) instead of `credential`
  3. Wrap a custom token source in a small adapter class exposing get_token(*scopes)

Example fix

# before
provider = pl.CredentialProviderAzure(credential="AccountKey=...")
# after
from azure.identity import ClientSecretCredential
provider = pl.CredentialProviderAzure(
    credential=ClientSecretCredential(tenant_id, client_id, client_secret)
)
Defensive patterns

Strategy: type-guard

Validate before calling

def validate_azure_credential(credential: object) -> None:
    if credential is not None and not (
        hasattr(credential, "get_token") and callable(credential.get_token)
    ):
        raise TypeError(
            "credential must be an azure.identity object exposing get_token(); "
            "pass raw keys via storage_options instead"
        )

Type guard

def is_token_credential(obj: object) -> bool:
    return obj is None or (hasattr(obj, "get_token") and callable(obj.get_token))

Try / catch

try:
    provider = pl.CredentialProviderAzure(credential=cred)
except ValueError as e:
    if "get_token()" in str(e):
        raise TypeError("pass an azure.identity credential, not a key/connection string") from e
    raise

Prevention

When it happens

Trigger: pl.CredentialProviderAzure(credential='AccountKey=...') (a connection string), credential={'client_id': ...} (a dict of secrets), or a BlobServiceClient instance - none expose get_token. ClientSecretCredential/DefaultAzureCredential/ManagedIdentityCredential all work.

Common situations: Config schemas whose 'credential' field actually holds an account key or connection string; passing the wrong azure SDK object; objects from older azure SDK versions lacking get_token.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/77fef9159caccc1d. Report an issue: GitHub.