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

OpenAI device-code authorization was denied

Error message

OpenAI device-code authorization was denied

What it means

While polling the OpenAI token endpoint, the response carried the OAuth error code access_denied — the user (or a policy) actively rejected the consent screen for the device code. This is a terminal outcome for the flow: polling stops immediately rather than continuing until expiry.

Source

Thrown at crates/zeroclaw-providers/src/auth/openai_oauth.rs:210

        if response.status().is_success() {
            return parse_token_response(response).await;
        }

        let status = response.status();
        let text = response.text().await.unwrap_or_default();

        if let Ok(err) = serde_json::from_str::<OAuthErrorResponse>(&text) {
            match err.error.as_str() {
                "authorization_pending" => {
                    continue;
                }
                "slow_down" => {
                    interval_secs = interval_secs.saturating_add(5);
                    continue;
                }
                "access_denied" => {
                    anyhow::bail!("OpenAI device-code authorization was denied")
                }
                "expired_token" => {
                    anyhow::bail!("OpenAI device-code expired")
                }
                _ => {
                    anyhow::bail!(
                        "OpenAI device-code polling failed ({status}): {}",
                        err.error_description.unwrap_or(err.error)
                    )
                }
            }
        }

        anyhow::bail!("OpenAI device-code polling failed ({status}): {text}");
    }
}

pub async fn receive_loopback_code(expected_state: &str, timeout: Duration) -> Result<String> {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Re-run the login and choose Allow on the consent screen, signing in with the account that should own the token
  2. If an org policy denies the app, use a personal/authorized account or have an admin allowlist the client
  3. Confirm the user_code belongs to your terminal session before approving, so you are not denying another flow
Defensive patterns

Strategy: try-catch

Try / catch

match openai_oauth::poll_device_code_tokens(&client, &device).await {
    Err(e) if e.to_string().contains("authorization was denied") => {
        // user intent: do not retry, surface guidance and stop
        anyhow::bail!("consent was denied — re-run `auth login --device-code` and choose Allow");
    }
    other => other,
}

Prevention

When it happens

Trigger: The user clicks 'Deny'/'Cancel' on the OpenAI device consent page while `zeroclaw auth login --model-provider openai-codex --device-code` is polling; or an org policy auto-denies the requested scopes.

Common situations: Consent screens showing suspicious-app warnings that scare users into denying, organizational SSO policies blocking the app, or the wrong browser account being used so the user denies in confusion.

Related errors


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