gitbutlerapp/gitbutler · error
Invalid GitHub base URL
Error message
Invalid GitHub base URL
What it means
When building the REST labels URL, `url.path_segments_mut()` returns `Err(())` if the parsed URL cannot have path segments (typically a `cannot-be-a-base` URL, e.g. a malformed or non-hierarchical `base_url` like `data:...` or an empty/invalid scheme). The library surfaces this as 'Invalid GitHub base URL'.
Solutions
- Check the configured GitHub base URL (config or env, e.g. for GitHub Enterprise) and correct it to a normal `https://host` URL.
- Test with `curl <base_url>/api/v3/...` (Enterprise) or `https://api.github.com` (public) to confirm the URL is well-formed.
- Remove trailing slashes/paths that may corrupt URL construction and re-test.
- If behind a custom proxy, ensure the proxy URL is a hierarchical http(s) URL.
Example fix
// before let base_url = "api.github.com"; // no scheme // after let base_url = "https://api.github.com"; // valid hierarchical base URL
Defensive patterns
Strategy: validation
Validate before calling
fn valid_base_url(base: &str) -> bool {
reqwest::Url::parse(base).map(|u| u.has_host() && u.can_be_a_base()).unwrap_or(false)
}
assert!(valid_base_url(base_url), "GitHub base URL must be a hierarchical http(s) URL"); Try / catch
match client.set_label(owner, repo, pr, label).await {
Err(e) if e.to_string().contains("Invalid GitHub base URL") => {
eprintln!("Fix the configured GitHub base URL (expected https://host)");
}
other => other?,
} Prevention
- Validate the GitHub base URL at config load time (scheme + host present)
- Use https://api.github.com for public GitHub and https://host/api/v3 for Enterprise
- Avoid placeholder or empty base URLs in config/env
When it happens
Trigger: Calling a labels-related client method with a configured GitHub base URL that parses but cannot hold path segments — e.g. a base URL missing a host, having an unsupported scheme, or being a non-hierarchical URL.
Common situations: Misconfigured GitHub Enterprise base URL (typo, missing `https://`, trailing garbage); pointing `base_url` at a proxy URL that is not a normal http(s) URL; env/config value set to an empty or placeholder string.
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
- Preferred GitHub account
- Refusing to remove label with degenerate name
- Unable to determine the forge for this project. Is target…
- Clone remote URL contains unsupported control characters
- configured storage path
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/321cdcc7f513b141.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-github/src/client.rs:2285
/// percent-encoded. `PathSegmentsMut::push` silently *drops* `.` and `..`
/// segments, which would degrade this into GitHub's remove-ALL-labels
/// endpoint — refuse those names instead of encoding them.
fn label_removal_url(
base_url: &str,
owner: &str,
repo: &str,
pr_number: i64,
label: &str,
) -> Result<reqwest::Url> {
if matches!(label, "" | "." | "..") {
bail!("Refusing to remove label with degenerate name {label:?}");
}
let mut url = reqwest::Url::parse(&format!(
"{base_url}/repos/{owner}/{repo}/issues/{pr_number}/labels"
))?;
url.path_segments_mut()
.map_err(|()| anyhow::anyhow!("Invalid GitHub base URL"))?
.push(label);
Ok(url)
}
/// A submitted review on a pull request, with the reactions left on it.
#[derive(Debug, Serialize)]
pub struct PullRequestReview {
pub id: i64,
pub author: Option<GitHubUser>,
/// GitHub state string: `APPROVED`, `CHANGES_REQUESTED`, `COMMENTED`,
/// `DISMISSED`, or `PENDING` (the caller's own unsubmitted draft).
pub state: String,
pub body: Option<String>,
pub submitted_at: Option<String>,
pub html_url: String,
pub reactions: Vec<Reaction>,
}
View on GitHub (pinned to 58e5313667)