gitbutlerapp/gitbutler · error
GitLabInvalidHost
GitLabInvalidHost
Error message
'{host}' is not an absolute URL. Use the full URL of your GitLab instance, for example https://gitlab.example.com What it means
new_with_host_override validates the GitLab instance base URL up front: it must parse as an absolute URL with a host (scheme + host), because reqwest otherwise fails only at request time with a generic error. The host the user supplied is relative or malformed.
Solutions
- Set the host to a full absolute URL, e.g. https://gitlab.example.com (scheme included)
- If using a self-hosted instance on a custom port, include it: https://gitlab.example.com:8443
- Fix the forge config value for the GitLab host and retry
Example fix
// before
let client = GitLabClient::new_with_host_override(storage, Some("gitlab.example.com"))?;
// after
let client = GitLabClient::new_with_host_override(storage, Some("https://gitlab.example.com"))?; Defensive patterns
Strategy: validation
Validate before calling
fn is_absolute_url(host: &str) -> bool {
reqwest::Url::parse(host).map(|u| u.has_host()).unwrap_or(false)
}
if !is_absolute_url(host) { eprintln!("Use full URL like https://gitlab.example.com"); } Prevention
- Always store GitLab hosts with scheme (https://) in config
- Validate host format at config-entry time, before client construction
- Include port in the stored URL for self-hosted instances
When it happens
Trigger: Calling new_with_host_override with a host like `gitlab.example.com` (no scheme) or `localhost:8080/api` fragments that fail reqwest::Url::parse or yield a URL without a host.
Common situations: User entered the instance host without https:// in forge config; trailing path mistakes; copy-paste losing the scheme; assuming a bare hostname is accepted like some git CLIs do.
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
- must be an HTTP or HTTPS URL
- Cannot pass both --local and --global
- Clone remote URL contains unsupported control characters
- Configured target branch has no branch name
- Configured target branch has no push remote
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/f7e82d9008934d1c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-gitlab/src/client.rs:114
);
let client = reqwest::Client::builder()
.default_headers(headers)
.timeout(GITLAB_REQUEST_TIMEOUT)
.build()?;
let base_url = if host.ends_with("/api/v4") {
host.to_string()
} else if host.ends_with('/') {
format!("{host}api/v4")
} else {
format!("{host}/api/v4")
};
// reqwest rejects a URL without a scheme and host at request time with a
// generic builder error; check the same rule up front so the user is told
// what is wrong with the host they entered.
if !reqwest::Url::parse(&base_url).is_ok_and(|url| url.has_host()) {
return Err(anyhow::anyhow!(
but_error::Context::new(format!(
"'{host}' is not an absolute URL. Use the full URL of your GitLab instance, for example https://gitlab.example.com"
))
.with_code(but_error::Code::GitLabInvalidHost)
));
}
Ok(Self { client, base_url })
}
pub async fn get_authenticated(&self) -> Result<AuthenticatedUser> {
#[derive(Deserialize)]
struct User {
username: String,
name: Option<String>,
email: Option<String>,
avatar_url: Option<String>,
}View on GitHub (pinned to 58e5313667)