Hmbown/CodeWhale · error
offers no browser sign-in flow
Error message
{} offers no browser sign-in flow What it means
During the PKCE browser sign-in flow, the provider's parameter set has no `authorize_path`, meaning no authorization endpoint is defined for it. The library refuses to construct an authorize URL because the provider (e.g. xAI) simply does not support browser-based OAuth sign-in. This is a guard so the flow fails with a clear reason instead of building a malformed or missing URL.
Solutions
- Use the device-code login flow for this provider instead (e.g. `codewhale auth xai-device`).
- Check `oauth_provider_params(provider)` for the chosen provider and pick one that defines `authorize_path`.
- If you own a custom provider config, add the correct `authorize_path` for its issuer.
Example fix
// before codewhale auth login --provider xai // browser flow, xAI has no authorize_path // after codewhale auth xai-device // device-code flow
Defensive patterns
Strategy: validation
Validate before calling
let params = oauth_provider_params(provider);
if params.authorize_path.is_none() {
// fall back to device-code flow instead of browser PKCE
return device_code_login(provider).await;
} Type guard
fn supports_browser_flow(params: &OAuthProviderParams) -> bool {
params.authorize_path.is_some()
} Prevention
- Check `authorize_path` support before choosing the browser login command.
- Use `codewhale auth xai-device` for xAI and other device-code-only providers.
- Keep custom provider param entries complete (authorize_path set) if browser login is expected.
When it happens
Trigger: Calling the internal authorize-URL builder (the function taking `scopes`, `redirect_uri`, `state`, `pkce`) with an `OAuthProviderParams` whose `authorize_path` is `None` — i.e. a provider configured without a browser authorization endpoint, such as xAI.
Common situations: Running `codewhale` browser login against a provider that only supports device-code login; a provider config/registry entry missing `authorize_path`; wiring a custom provider params struct without setting `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
- offers no browser sign-in flow; sign in through the…
- agy OAuth token JSON carries no access token member
- agy OAuth token member
- atomically replacing xAI OAuth credentials
- bearer credentials are not an API key
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/277f126f4ae5b354.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/oauth.rs:1147
let chunk = uuid::Uuid::new_v4();
let take = (bytes.len() - offset).min(16);
bytes[offset..offset + take].copy_from_slice(&chunk.as_bytes()[..take]);
offset += take;
}
URL_SAFE_NO_PAD.encode(bytes)
}
pub fn build_authorize_url(
params: &OAuthProviderParams,
issuer: &str,
client_id: &str,
scopes: &str,
redirect_uri: &str,
state: &str,
pkce: &PkceChallenge,
) -> Result<String> {
let Some(authorize_path) = params.authorize_path else {
bail!("{} offers no browser sign-in flow", params.display_name);
};
// A malformed configured issuer must fail loudly. Silently redirecting
// the browser to the production authorize endpoint would hand the
// issuer a sign-in the user aimed somewhere else.
let issuer_var = params
.env
.issuer_vars
.first()
.copied()
.unwrap_or("the issuer environment variable");
let mut url = oauth_endpoint_url(&format!(
"{}/{}",
issuer.trim_end_matches('/'),
authorize_path
))
.with_context(|| {
format!(
"{} OAuth issuer is not a valid URL or uses an insecure endpoint — check {issuer_var}",View on GitHub (pinned to 73e0f67d83)