Hmbown/CodeWhale · warning · anyhow::Error

Codewhale account login timed out; run `codewhale account lo

Error message

Codewhale account login timed out; run `codewhale account login` to try again

What it means

During OAuth device-code login polling, this bail fires when the elapsed time reaches the timeout (the lesser of the CLI's --timeout and the server-declared device code lifetime, clamped to 1 hour). It is the outer deadline check at the top of the polling loop: the user never completed authorization in the browser before the code expired or the client gave up.

Source

Thrown at crates/cli/src/cloud.rs:327

        expect_json(response, &[200])
    }

    fn poll_device(
        &self,
        device: &DeviceStart,
        timeout: Duration,
        sleep: &mut dyn FnMut(Duration),
    ) -> Result<AuthBundle> {
        validate_device_code(&device.device_code)?;
        let server_lifetime =
            Duration::from_secs(device.expires_in.clamp(1, MAX_LOGIN_TIMEOUT_SECONDS));
        let timeout = timeout.min(server_lifetime);
        let interval = Duration::from_secs(device.interval.clamp(1, 10));
        let started = Instant::now();

        loop {
            if started.elapsed() >= timeout {
                bail!(
                    "Codewhale account login timed out; run `codewhale account login` to try again"
                );
            }
            let response = self.transport.execute(CloudRequest {
                method: HttpMethod::Post,
                path: "/api/cli/device/token".to_string(),
                bearer: None,
                body: Some(json_body(&DeviceTokenRequest {
                    device_code: &device.device_code,
                })?),
            })?;
            match response.status {
                200 => {
                    let bundle: AuthBundle = parse_json_body(&response.body)?;
                    validate_auth_bundle(&bundle)?;
                    self.save_auth(bundle.clone())?;
                    return Ok(bundle);
                }

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Simply rerun `codewhale account login` and complete the browser authorization promptly using the printed user_code.
  2. If you routinely need longer, pass a larger --timeout (bounded by the server's device code lifetime, max 3600s).
  3. In headless environments, copy the verification_uri_complete URL to a machine with a browser and finish within the window.
  4. Check network access to the verification host if the page never loads.

Example fix

# before
codewhale account login --timeout 30
# (user needs ~2 minutes to authorize)

# after
codewhale account login --timeout 600
Defensive patterns

Strategy: retry

Try / catch

// CLI-internal; the user-facing pattern is rerunning the command
// Wrap automation: check for signed-in state before attempting account work
if !account_logged_in(profile)? {
    return run_login_with_timeout(profile, Duration::from_secs(600));
}

Prevention

When it happens

Trigger: User starts `codewhale account login`, never opens the verification URL (or doesn't approve it), and the min(--timeout, device.expires_in) deadline passes; headless terminal where nobody can open the browser; verification page unreachable.

Common situations: Unattended/CI shells where the device flow stalls, slow mail relay for the login link, user stepped away, or a --timeout value smaller than the time the user needed to authorize.

Understand the failure class

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/767737ecedd53821. Report an issue: GitHub.