Hmbown/CodeWhale · error

{message}

Error message

{message}

What it means

During the OAuth device-code flow, `timed_out` builds the terminal error when polling exceeds the allowed window. With `saw_slow_down == true` and a provider-specific `slow_down_timeout_message` configured, that message is returned instead of the generic timeout message. It lets each provider describe its own slow-down policy failure.

Solutions

  1. Restart the device-code login (`codewhale auth login` or equivalent) and complete verification promptly.
  2. Open the verification URL immediately when shown and enter the code without long delays.
  3. If it persists, check the provider's status page — persistent slow_down can indicate rate limiting on the account.
Defensive patterns

Strategy: retry

Try / catch

match auth.login_device_code() {
    Err(e) if e.to_string().contains("slow") || e.to_string().contains("timed out") => {
        eprintln!("Restart login and complete verification promptly.");
        auth.login_device_code()?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: The device-code polling loop (`run`) receives `slow_down` responses from the provider and ultimately exhausts its retry/timeout budget, and the device-code config supplies a `slow_down_timeout_message`.

Common situations: User delayed too long between opening the verification URL and entering the code, causing repeated `slow_down` responses until the flow times out.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/767c87e02a6a0b62. Report an issue: GitHub.

Appendix: source

Thrown at crates/config/src/device_code.rs:173

                        }
                    };
                }
            }

            // Never sleep past the code's expiry, even after slow_down backoff.
            let remaining = deadline.saturating_duration_since(Instant::now());
            if remaining.is_zero() {
                break;
            }
            sleep(interval.min(remaining));
        }

        Err(self.timed_out(saw_slow_down))
    }

    fn timed_out(&self, saw_slow_down: bool) -> anyhow::Error {
        match (saw_slow_down, self.slow_down_timeout_message.as_deref()) {
            (true, Some(message)) => anyhow::anyhow!("{message}"),
            _ => anyhow::anyhow!("{}", self.timeout_message),
        }
    }
}

/// Reject a device-code verification URI that must not be handed to a browser
/// opener.
///
/// Ported from pi's `validateVerificationUri`
/// (`packages/ai/src/auth/oauth/xai.ts`, MIT, Copyright (c) 2025 Mario
/// Zechner): the URI comes straight off the wire and is passed to the platform
/// "open this" call, so a malicious or compromised response could otherwise
/// launch `file:`, a custom app scheme, or a helper with attacker-chosen
/// arguments. pi requires `https:`; Codewhale additionally allows `http:` on a
/// loopback host, which is what self-hosted issuers and the device-code tests
/// use — matching the loopback allowance the account login already makes.
///
/// Embedded credentials are rejected in every case.

View on GitHub (pinned to 73e0f67d83)