Hmbown/CodeWhale · error
offers no browser sign-in flow; sign in through the…
Error message
{} offers no browser sign-in flow; sign in through the device-code login instead What it means
Entry point for the browser-based PKCE login. Before binding any listener or opening a browser, it checks whether the provider defines an `authorize_path`; providers without a browser flow (xAI) are rejected up front with a message pointing at the device-code alternative.
Solutions
- Run the device-code login instead: `codewhale auth xai-device`.
- Select a provider that supports the browser flow if browser sign-in is what you want.
- If adding a new provider, define `authorize_path` in its `OAuthProviderParams` to enable browser login.
Example fix
// before let pending = pkce_login(OAuthProvider::Xai).await?; // bails // after let pending = device_code_login(OAuthProvider::Xai).await?; // or codewhale auth xai-device
Defensive patterns
Strategy: fallback
Validate before calling
let params = oauth_provider_params(provider);
let use_browser = params.authorize_path.is_some();
if !use_browser { return device_code_login(provider).await; } Type guard
fn has_browser_login(provider: OAuthProvider) -> bool {
oauth_provider_params(provider).authorize_path.is_some()
} Prevention
- Route device-code-only providers (xAI) to their device login command from the start.
- Consult `oauth_provider_params` capabilities before presenting a 'Sign in with browser' option.
- Define `authorize_path` for any new provider you want on the browser flow.
When it happens
Trigger: Calling `pkce_login(provider)` where `oauth_provider_params(provider).authorize_path` is `None` — currently the xAI provider.
Common situations: Running the generic browser login command with a device-code-only provider selected; scripting `pkce_login` for xAI; provider registry entry lacking `authorize_path`.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- returned an unusable verification URI
- {}
- offers no device-code flow; sign in through the browser…
- {message}
- offers no browser sign-in flow
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8450766e126004a8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/oauth.rs:1483
&[
("grant_type", "authorization_code"),
("client_id", client_id),
("redirect_uri", redirect_uri),
("code", code),
("code_verifier", verifier),
],
)?;
parse_oauth_form_response(status, &body, "authorization code exchange", params)
}
/// Interactive PKCE browser login for any provider whose row offers it.
/// Prints the authorize URL, opens a browser, and waits for the loopback
/// callback. A provider with no browser flow (xAI) fails here with the
/// reason, before any listener binds.
pub async fn pkce_login(provider: OAuthProvider) -> Result<PendingOAuthLogin> {
let params = oauth_provider_params(provider);
if params.authorize_path.is_none() {
bail!(
"{} offers no browser sign-in flow; sign in through the device-code login instead",
params.display_name
);
}
let inputs = params.resolve_inputs();
let display_name = params.display_name;
tokio::task::spawn_blocking(move || pkce_login_with(provider, &inputs))
.await
.with_context(|| format!("{display_name} PKCE login worker failed"))?
}
/// Blocking worker body for [`pkce_login`]. `pub(crate)` so the activation
/// tests can drive the unified login end to end until activation unifies.
pub(crate) fn pkce_login_with(
provider: OAuthProvider,
inputs: &ResolvedOAuthInputs,
) -> Result<PendingOAuthLogin> {
let params = oauth_provider_params(provider);View on GitHub (pinned to 73e0f67d83)