Hmbown/CodeWhale · error · anyhow::Error
Browser login is only enabled for the canonical Codewhale ac
Error message
Browser login is only enabled for the canonical Codewhale account API or a loopback test API
What it means
Browser login is hard-gated to two API environments: the canonical https://api.codewhale.net:443 or a loopback test API. If --api-base (or the configured account API base URL) is anything else - any other HTTPS host - this bail fires before any URL is validated: device-flow login simply does not run against third-party endpoints.
Source
Thrown at crates/cli/src/cloud.rs:824
let api = Url::parse(api_base).context("invalid Codewhale account API base URL")?;
let canonical_api = api.scheme() == "https"
&& api.host_str() == Some("api.codewhale.net")
&& api.port_or_known_default() == Some(443);
let loopback_api = api.host_str().is_some_and(is_loopback_host);
if canonical_api {
if url.scheme() != "https"
|| !host.eq_ignore_ascii_case("app.codewhale.net")
|| url.port_or_known_default() != Some(443)
{
bail!("The Codewhale service returned an untrusted verification origin");
}
} else if loopback_api {
if !matches!(url.scheme(), "http" | "https") || !is_loopback_host(host) {
bail!("The Codewhale service returned an untrusted verification origin");
}
} else {
bail!(
"Browser login is only enabled for the canonical Codewhale account API or a loopback test API"
);
}
let query = url.query_pairs().collect::<Vec<_>>();
if complete {
if query.len() != 1 || query[0].0 != "user_code" || query[0].1 != user_code {
bail!("The Codewhale service returned an unsafe verification URL");
}
} else if !query.is_empty() {
bail!("The Codewhale service returned an unsafe verification URL");
}
Ok(url.to_string())
}
fn is_loopback_host(host: &str) -> bool {
let host = host
.strip_prefix('[')View on GitHub (pinned to 0c42157ee5)
Solutions
- For custom endpoints, authenticate with an API key (e.g. --api-key-stdin) instead of browser login
- Use the canonical --api-base https://api.codewhale.net for browser login
- For testing browser login locally, run the API on a loopback host (localhost/127.0.0.1/::1)
- Check for and remove an explicit non-443 port on the api.codewhale.net base, which disqualifies it as canonical
Example fix
# before codewhale cloud login --api-base https://staging.codewhale.net # after codewhale cloud login --provider <provider> --api-key-stdin # key auth for custom endpoints
Defensive patterns
Strategy: validation
Validate before calling
fn browser_login_supported(api_base: &str) -> bool {
match url::Url::parse(api_base) {
Ok(api) => {
let canonical = api.scheme() == "https"
&& api.host_str() == Some("api.codewhale.net")
&& api.port_or_known_default() == Some(443);
canonical || api.host_str().is_some_and(is_loopback_host)
}
Err(_) => false,
}
}
if !browser_login_supported(api_base) { /* use API-key auth path */ } Prevention
- Gate browser login on environment before starting the device flow
- Script non-canonical deployments with API-key auth (--api-key-stdin) from the start
- Validate --api-base early with the same canonical/loopback predicate in setup scripts
When it happens
Trigger: Starting browser login with --api-base https://staging.codewhale.net, https://api.codewhale.net:8443, or any custom/private HTTPS host that is not loopback and not exactly api.codewhale.net on port 443.
Common situations: Enterprise or self-hosted deployments pointing the CLI at an internal API; staging environments; typos in the configured API base; http:// on a non-loopback host (also rejected earlier by validate_api_base).
Related errors
- Codewhale account login timed out; run `codewhale account lo
- The Codewhale service returned an unsafe verification URL
- The Codewhale service returned an untrusted verification ori
- The Codewhale service returned an invalid user code
- The Codewhale service returned an invalid device authorizati
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/06855256eea4df4e.
Report an issue: GitHub.