gitbutlerapp/gitbutler · error
Failed to get repo
Error message
Failed to get repo: {} What it means
GitHubClient::get_repo fetches /repos/{owner}/{repo} to inspect repository metadata (e.g. whether the user can merge a PR). Any non-2xx status from GitHub results in this bail with the HTTP status. Typically means the repo does not exist or is inaccessible with the current credentials.
Solutions
- Verify owner/repo with curl -H "Authorization: Bearer $TOKEN" https://api.github.com/repos/{owner}/{repo}
- Check token scopes/permissions; regenerate with repo (or fine-grained repository read) access
- Watch for 403 with rate-limit headers; wait for reset or use a token with higher limits
Example fix
// before
let repo = client.get_repo("acme", "reppo").await?; // typo
// after
let repo = client.get_repo("acme", "repo").await?; // verified via API Defensive patterns
Strategy: try-catch
Validate before calling
let status = reqwest::Client::new()
.get(&format!("https://api.github.com/repos/{owner}/{repo}"))
.header("Authorization", format!("Bearer {token}"))
.send().await?.status();
if !status.is_success() { return Err(format!("repo unreachable: {status}")); } Try / catch
match client.get_repo(owner, repo).await {
Ok(r) => r,
Err(e) if e.to_string().contains("Failed to get repo: 403") => {
// rate-limited or forbidden: back off / check scopes
...
}
Err(e) => return Err(e),
} Prevention
- Verify owner/repo slugs before calling
- Use a token with repository read access (repo scope or fine-grained read)
- Watch rate-limit headers and back off on 403
When it happens
Trigger: Calling get_repo with an owner/repo that doesn't exist, is private and the token lacks access, or the API returns 403/404/5xx.
Common situations: Renamed or deleted repository; token missing 'repo' scope for a private repo; typo'd owner/repo; hitting a rate limit (403); corporate proxy blocking api.github.com.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Failed to add labels
- Failed to add to GitHub stack
- Failed to create GitHub stack
- Failed to get PR base repo
- Failed to list GitHub stacks
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/0d417a30f07272ca.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-github/src/client.rs:160
let user: User = response.json().await?;
Ok(AuthenticatedUser {
login: user.login,
avatar_url: user.avatar_url,
name: user.name,
email: user.email,
})
}
/// Fetch repo-level metadata (currently just the caller's permissions
/// and whether the repo is a fork). Used by the desktop to decide
/// whether the authenticated user can merge a given PR.
pub async fn get_repo(&self, owner: &str, repo: &str) -> Result<GitHubRepository> {
let url = format!("{}/repos/{}/{}", self.base_url, owner, repo);
let response = self.client.get(&url).send().await?;
if !response.status().is_success() {
bail!("Failed to get repo: {}", response.status());
}
Ok(response.json().await?)
}
/// Fetch CI checks for a branch ref, paginated and deduped by name.
pub async fn list_checks_for_ref(
&self,
owner: &str,
repo: &str,
reference: &str,
) -> Result<Vec<CheckRun>> {
#[derive(Deserialize)]
struct CheckRunsResponse {
total_count: usize,
check_runs: Vec<CheckRun>,
}
let url = format!(View on GitHub (pinned to 58e5313667)