Hmbown/CodeWhale · error · anyhow::Error

Codewhale account API base URL must be an origin without a…

Error message

Codewhale account API base URL must be an origin without a path

What it means

The API base URL must be an origin with no path component: validate_api_base allows only an empty path or /. The client constructs its own /api/... request paths, so a pre-set path would produce wrong URLs.

Solutions

  1. Remove the path, keeping only scheme+host (and optional port): https://api.example.com.
  2. Do not add /v1 or /api — the client appends its API paths itself.
  3. Retry with the origin-only value.

Example fix

// before
CODEWHALE_API_BASE=https://api.example.com/v1
// after
CODEWHALE_API_BASE=https://api.example.com
Defensive patterns

Strategy: validation

Validate before calling

fn has_no_path(url: &str) -> bool {
    url::Url::parse(url.trim())
        .map(|u| matches!(u.path(), "" | "/"))
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: Setting the base URL to something like https://api.example.com/v1 or https://example.com/api/codewhale.

Common situations: Reusing a base URL from another SDK that expects a path prefix (e.g. OpenAI-style /v1); pasting a full endpoint URL instead of the origin.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

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

    writeln!(out, "API: {api_base}")?;
    Ok(())
}

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,

View on GitHub (pinned to 73e0f67d83)