Hmbown/CodeWhale · error

sign-in was not completed

Error message

sign-in was not completed: {detail}

What it means

The OAuth provider redirected back to the loopback callback with an `error` parameter (and optionally an `error_description`), so sign-in did not complete. The library surfaces the provider's description (or bare error code) to the user. This is how authorization failures like `access_denied` reach the caller.

Solutions

  1. Read `detail` in the message — it names the provider-side OAuth error (e.g. `access_denied`).
  2. Retry the sign-in and approve the consent screen when the browser opens.
  3. Fix the app registration (approved scopes, allowed redirect URI `http://localhost:<port>`) on the provider, then sign in again.
Defensive patterns

Strategy: try-catch

Try / catch

match pkce_login(provider).await {
    Ok(pending) => { /* proceed */ }
    Err(e) if e.to_string().starts_with("sign-in was not completed") => {
        // surface provider detail, prompt user to retry and approve consent
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: The browser callback hits the local listener with `?error=...`; the state matched the pending login but the provider reported an OAuth error — e.g. the user clicked 'Cancel'/'Deny' on the consent screen, the app is unapproved, or scopes were rejected.

Common situations: User denies the consent prompt; OAuth app not yet approved/installed on the provider tenant; requesting scopes the app isn't allowed; expired or reused sign-in attempt rejected by the provider.

Related errors


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

Appendix: source

Thrown at crates/tui/src/oauth.rs:1241

                "OAuth callback state did not match the pending login"
            );
            Ok(code)
        }
        CallbackOutcome::Error {
            error,
            description,
            state,
        } => {
            if let Some(state) = state {
                anyhow::ensure!(
                    state == expected_state,
                    "OAuth error callback state did not match the pending login"
                );
            }
            let detail = description
                .filter(|text| !text.trim().is_empty())
                .unwrap_or(error);
            bail!("sign-in was not completed: {detail}")
        }
    }
}

fn parse_http_request_target(request_line: &str) -> Result<String> {
    let mut parts = request_line.split_whitespace();
    let method = parts.next().unwrap_or_default();
    anyhow::ensure!(
        method.eq_ignore_ascii_case("GET"),
        "OAuth callback must be GET"
    );
    let target = parts
        .next()
        .context("OAuth callback missing request target")?;
    Ok(target.to_string())
}

fn query_from_target<'a>(params: &OAuthProviderParams, target: &'a str) -> Result<&'a str> {

View on GitHub (pinned to 73e0f67d83)