zeroclaw-labs/zeroclaw · warning · anyhow::Error

`auth refresh` is not supported for this provider. Only Open

Error message

`auth refresh` is not supported for this provider. Only OpenAI Codex and Gemini have an in-process token-refresh flow.

What it means

Default AuthProviderImpl::refresh_status, inherited by providers with no in-process token refresh. Only OpenAI Codex and Gemini override it with a real refresh flow; bearer-token providers store static keys that never refresh, so `auth refresh` bails with this message instead of pretending to succeed. handle_auth_command routes the `auth refresh` subcommand here.

Source

Thrown at crates/zeroclaw-providers/src/auth/mod.rs:1078

        _ctx: &AuthFlowContext<'_>,
        _profile: &str,
        _input: Option<&str>,
    ) -> Result<()> {
        anyhow::bail!(
            "`auth paste-redirect` is not supported for this provider. Only OpenAI Codex and \
             Gemini expose a browser-based OAuth flow.",
        )
    }

    /// Refresh the access token for `profile_override` (or active
    /// profile) and report status. Default impl bails for providers
    /// without a refresh flow.
    async fn refresh_status(
        &self,
        _ctx: &AuthFlowContext<'_>,
        _profile_override: Option<&str>,
    ) -> Result<RefreshStatus> {
        anyhow::bail!(
            "`auth refresh` is not supported for this provider. Only OpenAI Codex and Gemini \
             have an in-process token-refresh flow.",
        )
    }
}

impl AuthProvider {
    /// Resolve the per-variant `AuthProviderFlow` impl for trait dispatch.
    /// The `match self` here is on enum variants — the only place an
    /// auth-flow dispatch exists, every other call site routes through
    /// the returned trait object.
    pub fn flow(&self) -> Box<dyn AuthProviderFlow> {
        match self {
            Self::OpenaiCodex => Box::new(OpenaiCodexFlow),
            Self::Gemini => Box::new(GeminiFlow),
            Self::Anthropic => Box::new(AnthropicFlow),
            Self::Xai => Box::new(XaiFlow),
        }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Skip `auth refresh` for bearer providers — the stored key does not expire via OAuth; rotate it with `auth paste-token` when it changes
  2. Target a refreshable provider explicitly: `zeroclaw auth refresh --model-provider openai-codex` or `--model-provider gemini`
  3. Filter provider lists in automation to only refresh-supported providers

Example fix

# before: blanket refresh over all providers
for p in anthropic openai-codex gemini; do zeroclaw auth refresh --model-provider $p; done

# after: refresh only providers with an in-process flow
for p in openai-codex gemini; do zeroclaw auth refresh --model-provider $p; done
Defensive patterns

Strategy: fallback

Try / catch

match provider.refresh_status(ctx, None).await {
    Ok(status) => Ok(status),
    Err(e) if e.to_string().contains("auth refresh` is not supported") => {
        Ok(RefreshStatus::NotRefreshable) // bearer tokens: nothing to refresh
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Running `zeroclaw auth refresh --model-provider <bearer-provider>` (or with that provider active) for a provider without a refresh implementation.

Common situations: Automated token-rotation scripts applied uniformly to every configured provider, or refreshing after switching the active provider to an API-key one.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/187df14c2b409a60. Report an issue: GitHub.