Hmbown/CodeWhale · error

Codewhale account API base URL must include a host

Error message

Codewhale account API base URL must include a host

What it means

validate_api_base hardens the Codewhale account API base URL (config/env override of the default api.codewhale.net origin). After already rejecting embedded credentials, query/fragment, and any path beyond "/", it requires a host. Url::parse can succeed for non-special schemes with no authority (mailto:, data:, unix:), and those hostless URLs are rejected here.

Source

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

struct ValidatedApiBase {
    url: Url,
    display: String,
}

fn validate_api_base(value: &str) -> Result<ValidatedApiBase> {
    let mut url = Url::parse(value.trim()).context("invalid Codewhale account API base URL")?;
    if !url.username().is_empty() || url.password().is_some() {
        bail!("Codewhale account API base URL must not contain credentials");
    }
    if url.query().is_some() || url.fragment().is_some() {
        bail!("Codewhale account API base URL must not contain a query or fragment");
    }
    if !matches!(url.path(), "" | "/") {
        bail!("Codewhale account API base URL must be an origin without a path");
    }
    let host = url
        .host_str()
        .ok_or_else(|| anyhow!("Codewhale account API base URL must include a host"))?;
    let allowed = url.scheme() == "https" || (url.scheme() == "http" && is_loopback_host(host));
    if !allowed {
        bail!(
            "Codewhale account API base URL must use HTTPS (loopback HTTP is allowed for testing)"
        );
    }
    url.set_path("/");
    let display = url.as_str().trim_end_matches('/').to_string();
    Ok(ValidatedApiBase { url, display })
}

fn validate_verification_url(
    value: &str,
    api_base: &str,
    user_code: &str,
    complete: bool,
) -> Result<String> {
    let url =

View on GitHub (pinned to 8880682c63)

Solutions

  1. Set the full origin, e.g. https://api.codewhale.net (or http://127.0.0.1:PORT for loopback testing)
  2. Unset the custom API base override to fall back to the canonical default
  3. Check the config for stray characters or a missing scheme before the host

Example fix

# before
 codewhale cloud login --api-base unix:///run/cw.sock   # error: must include a host

# after
 codewhale cloud login --api-base https://api.codewhale.net
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_api_base(value: &str) -> bool {
    let Ok(url) = url::Url::parse(value.trim()) else { return false };
    url.host_str().is_some_and(|h| !h.is_empty())
        && url.username().is_empty()
        && url.password().is_none()
        && !url.query().is_some()
        && !url.fragment().is_some()
        && matches!(url.path(), "" | "/")
        && (url.scheme() == "https" || url.scheme() == "http" && h_is_loopback(url))
}

Prevention

When it happens

Trigger: Setting the account API base to a hostless URL that still parses: "mailto:support@codewhale.net", "data:text/plain,x", "unix:///run/codewhale.sock", "about:blank". Reached via the api-base config key or the CODEWHALE_API_BASE-style override on any cloud command.

Common situations: Typo dropping the https:// scheme and pasting a bare URI; attempting to point the CLI at a unix socket; copy-pasting a data/mailto link into config.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/8b4d3dc218c3d339. Report an issue: GitHub.