NousResearch/hermes-agent · error · ValueError

token provider returned empty value

Error message

token provider returned empty value

What it means

materialize_bearer_for_http() accepted a zero-arg callable token provider and invoked it, but the callable returned None or an empty/non-string value. In practice the callable wraps DefaultAzureCredential/azure-identity chain minting an Entra bearer JWT; an empty token means the credential chain ran but produced nothing usable.

Source

Thrown at agent/azure_identity_adapter.py:471

    header outside the OpenAI SDK (e.g. ``hermes_cli/azure_detect.py``).
    Calls the callable exactly once and returns the resulting token.

    **Anthropic SDK integration:** the Anthropic Python SDK does not
    accept a ``Callable[[], str]`` for ``auth_token``. Instead,
    :func:`build_bearer_http_client` returns an ``httpx.Client`` whose
    request event hook calls this function and rewrites the
    ``Authorization`` header per request — and that client is passed to
    the Anthropic SDK via ``http_client=...``. See
    :func:`agent.anthropic_adapter.build_anthropic_client` for the
    consumer.

    Raises ``ValueError`` if ``value`` is not a callable token provider
    or non-empty string.
    """
    if is_token_provider(value):
        token = value()
        if not isinstance(token, str) or not token:
            raise ValueError("token provider returned empty value")
        return token
    if isinstance(value, str) and value:
        return value
    raise ValueError("no usable api_key / token provider")


def build_bearer_http_client(token_provider: Callable[[], str], **httpx_kwargs: Any) -> Any:
    """Return an ``httpx.Client`` that mints a fresh Entra bearer JWT
    per outbound request.

    The Anthropic SDK (≤ 0.86.0 at the time of writing) stores
    ``api_key`` / ``auth_token`` as static strings and computes the
    ``Authorization`` header at construction time. To get per-request
    token refresh (the Microsoft-recommended Foundry pattern for
    callable bearer providers), we install an httpx ``request`` event
    hook on a custom client and pass that client to the SDK via
    ``http_client=...``. The hook:

View on GitHub (pinned to c896c09c42)

Solutions

  1. Re-authenticate: `az login` (and `az account set --subscription ...`).
  2. Verify the credential chain works standalone: `az account get-access-token --resource https://ai.azure.com` (or the Foundry resource) in the same shell.
  3. Set required AZURE_* env vars (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET for service principals).
  4. If it is a custom token provider, make it raise on failure instead of returning None/empty.

Example fix

# custom token provider — before
async def token_provider():
    return await cache.get("token")  # may be None
# after
def token_provider() -> str:
    token = fetch_entra_token()
    if not token:
        raise RuntimeError("failed to acquire Entra token")
    return token
Defensive patterns

Strategy: validation

Validate before calling

def token_ok(provider) -> bool:
    try:
        t = provider()
    except Exception:
        return False
    return isinstance(t, str) and bool(t)
assert token_ok(my_token_provider), "Entra token provider yields no usable token"

Type guard

def is_usable_token_provider(fn) -> bool:
    if not callable(fn):
        return False
    try:
        t = fn()
    except Exception:
        return False
    return isinstance(t, str) and len(t) > 0

Try / catch

try:
    client = build_bearer_http_client(token_provider)
    ...  # first request
except ValueError as e:
    if "token provider returned empty value" in str(e):
        relogin_or_refresh_credentials()  # az login etc.

Prevention

When it happens

Trigger: build_bearer_http_client(token_provider) where token_provider() returns '' or None — e.g. azure credential chain silently exhausted, or a custom provider function with a bug returning nothing on error (agent/azure_identity_adapter.py:471).

Common situations: `az login` expired; managed identity unavailable (wrong VM/containers environment); tenant/subscription env vars (AZURE_TENANT_ID etc.) misconfigured; a stub token provider in tests returning None.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/029e15484d547697. Report an issue: GitHub.