zed-industries/zed · error

failed to get host from forgejo base url

Error message

failed to get host from forgejo base url

What it means

The Forgejo provider needs the hostname of its stored base_url to build API endpoints of the form https://{host}/api/v1/repos/{owner}/{repo}/git/commits/{sha}. Url::host_str() returns None when the parsed URL carries no host component, so the code bails before it can construct the request URL. This is almost always a misconfigured provider URL rather than a network failure.

Source

Thrown at crates/git_hosting_providers/src/providers/forgejo.rs:116

        if !host.contains("forgejo") {
            bail!("not a Forgejo URL");
        }

        Ok(Self::new(
            "Forgejo Self-Hosted",
            Url::parse(&format!("https://{}", host))?,
        ))
    }

    async fn fetch_forgejo_commit_author(
        &self,
        repo_owner: &str,
        repo: &str,
        commit: &str,
        client: &Arc<dyn HttpClient>,
    ) -> Result<Option<User>> {
        let Some(host) = self.base_url.host_str() else {
            bail!("failed to get host from forgejo base url");
        };
        let url = format!(
            "https://{host}/api/v1/repos/{repo_owner}/{repo}/git/commits/{commit}?stat=false&verification=false&files=false"
        );

        let mut request = Request::get(&url)
            .header("Content-Type", "application/json")
            .follow_redirects(http_client::RedirectPolicy::FollowAll);

        // TODO: not renamed yet for compatibility reasons, may require a refactor later
        // see https://github.com/zed-industries/zed/issues/11043#issuecomment-3480446231
        if host == "codeberg.org"
            && let Ok(codeberg_token) = std::env::var("CODEBERG_TOKEN")
        {
            request = request.header("Authorization", format!("Bearer {}", codeberg_token));
        }

        let mut response = client

View on GitHub (pinned to f4178619ac)

Solutions

  1. Set the Forgejo base URL to a fully-qualified form such as https://forgejo.example.com
  2. Validate at provider construction: parse the URL and ensure host_str() is Some and non-empty, so the bad value is rejected early with the offending string in the message
  3. Normalize and verify URL inputs in the settings layer before a provider is created

Example fix

// before
let base_url = Url::parse(&raw_url)?; // may lack a host; fails later inside fetch_forgejo_commit_author

// after: fail fast at construction with the offending value
let base_url = Url::parse(&raw_url)?;
anyhow::ensure!(
    base_url.host_str().is_some_and(|h| !h.is_empty()),
    "forgejo base url '{raw_url}' has no host"
);
Defensive patterns

Strategy: validation

Validate before calling

// run before constructing/calling the provider
let parsed = Url::parse(&configured_url)?;
anyhow::ensure!(
    parsed.host_str().is_some_and(|host| !host.is_empty()),
    "forgejo url '{configured_url}' must include scheme and host"
);

Type guard

fn has_url_host(url: &Url) -> bool {
    url.host_str().is_some_and(|h| !h.is_empty())
}

Try / catch

match fetch_commit_author(owner, repo, sha).await {
    Ok(author) => { /* ... */ }
    Err(err) if err.to_string().contains("failed to get host") => {
        // configuration problem: surface it, do not retry
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Instantiating a Forgejo provider whose base_url parses as a URL but has no authority component (e.g. file:///path, unix:/run/forgejo.sock, data:..., or an empty/relative string that slipped through construction), then invoking any code path that reaches fetch_forgejo_commit_author (commit author enrichment for a permalink).

Common situations: Settings where the Forgejo URL was entered without a scheme or host (e.g. a raw 'forgejo.mycompany.com'), test fixtures using placeholder URLs, or refactors that pass an already-stripped URL into the provider.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/d3ba43521b8d1b6f. Report an issue: GitHub.