gitbutlerapp/gitbutler · error · anyhow::Error

{error_message}: {}

Error message

{error_message}: {}

What it means

A GET request while listing GitLab merge requests returned a non-2xx status. The message prefixes the caller-supplied context (which listing failed) and appends the HTTP status code.

Source

Thrown at crates/but-gitlab/src/client.rs:209

    ) -> Result<Vec<MergeRequest>> {
        let mut mrs = Vec::new();
        let mut next_page = Some("1".to_string());
        let mut seen_pages = HashSet::new();

        while let Some(page) = next_page.take() {
            if !merge_request_page_is_safe(&page, &mut seen_pages) {
                bail!("Stopped listing GitLab merge requests after unsafe pagination state");
            }

            let response = self
                .client
                .get(url)
                .query(query)
                .query(&[("per_page", "100"), ("page", page.as_str())])
                .send()
                .await?;
            if !response.status().is_success() {
                bail!("{error_message}: {}", response.status());
            }

            next_page = next_page_from_headers(response.headers());
            let mut page_mrs: Vec<GitLabMergeRequest> = response.json().await?;
            if page_mrs.is_empty() {
                break;
            }
            mrs.append(&mut page_mrs);
        }

        let mut seen = HashSet::new();
        Ok(mrs
            .into_iter()
            .filter(|mr| seen.insert(mr.iid))
            .map(Into::into)
            .collect())
    }

View on GitHub (pinned to caf1f223d3)

Solutions

  1. 401: re-authenticate the GitLab token
  2. 403: add the api (or read_api) scope to the token
  3. 404: fix the project path/id used in the URL
  4. 429/5xx: retry with backoff
Defensive patterns

Strategy: retry

Try / catch

for attempt in 0..3 {
    match client.list_merge_requests(...).await {
        Ok(mrs) => break Ok(mrs),
        Err(e) if e.to_string().ends_with("401 Unauthorized") => break Err(e.context("re-authenticate GitLab token")),
        Err(e) if e.to_string().ends_with("404 Not Found") => break Err(e.context("check project path/id")),
        Err(e) => tokio::time::sleep(exp_backoff(attempt)).await,
    }
}

Prevention

When it happens

Trigger: 401 expired GitLab token; 403 token lacks the api or read_api scope; 404 wrong project path or id in the URL; 429 rate limit; 5xx under GitLab load.

Common situations: Long-lived sessions with expired tokens; wrong project identifiers; heavy automation against self-hosted GitLab.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/08bdcfe85bfeee6b. Report an issue: GitHub.