gitbutlerapp/gitbutler · error · anyhow::Error

Failed to list jobs for pipeline: {}

Error message

Failed to list jobs for pipeline: {}

What it means

Thrown inside list_pipeline_jobs_for_ref when one page request of GET /projects/:id/pipelines/:id/jobs (per_page=100&page=N) returns a non-2xx status after the initial pipeline lookup already succeeded. Distinct from the context-wrapped transport error ('Failed to list GitLab jobs for pipeline {id}') which fires if the request never completes — this bail means GitLab answered and refused. Because it happens mid-pagination, all jobs accumulated so far are discarded.

Source

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

                bail!(
                    "Stopped listing GitLab jobs for pipeline {} after unsafe pagination state",
                    pipeline.id
                );
            }
            pages_iterated += 1;

            let response = self
                .client
                .get(&jobs_url)
                .query(&[("per_page", "100"), ("page", page.as_str())])
                .send()
                .await
                .with_context(|| {
                    format!("Failed to list GitLab jobs for pipeline {}", pipeline.id)
                })?;

            if !response.status().is_success() {
                bail!("Failed to list jobs for pipeline: {}", response.status());
            }

            next_page = next_page_from_headers(response.headers());
            let mut page_jobs: Vec<GitLabPipelineJob> =
                response.json().await.with_context(|| {
                    format!("Failed to parse GitLab jobs for pipeline {}", pipeline.id)
                })?;
            if page_jobs.is_empty() {
                break;
            }
            jobs.append(&mut page_jobs);
        }

        let jobs = normalize_pipeline_jobs(
            jobs,
            pipeline_web_url,
            pipeline_status,
            &self.base_url,

View on GitHub (pinned to caf1f223d3)

Solutions

  1. For 429: back off (honor Retry-After) and restart the listing — this client does not cache partial pages
  2. For 401: re-run `but config forge auth` and retry
  3. For 5xx: retry with exponential backoff; check GitLab status
  4. Reduce polling frequency of large pipelines to stay under rate limits

Example fix

// before
let jobs = client.list_pipeline_jobs_for_ref(project_id, branch).await?;

// after: retry once after backoff for transient mid-pagination failures
let jobs = match client.list_pipeline_jobs_for_ref(project_id.clone(), branch).await {
    Ok(jobs) => jobs,
    Err(err) => {
        let s = err.to_string();
        if s.contains("429") || s.contains("500") || s.contains("502") || s.contains("503") {
            tokio::time::sleep(Duration::from_secs(5)).await;
            client.list_pipeline_jobs_for_ref(project_id, branch).await?
        } else {
            return Err(err);
        }
    }
};
Defensive patterns

Strategy: retry

Try / catch

async fn list_jobs_with_retry(client: &GitLabClient, project_id: GitLabProjectId, branch: &str) -> Result<Vec<GitLabPipelineJob>> {
    match client.list_pipeline_jobs_for_ref(project_id.clone(), branch).await {
        Ok(jobs) => Ok(jobs),
        Err(err) => {
            let m = err.to_string();
            if m.contains("429") || m.contains("50") { // transient: retry once after backoff
                tokio::time::sleep(std::time::Duration::from_secs(5)).await;
                client.list_pipeline_jobs_for_ref(project_id, branch).await
            } else { Err(err) }
        }
    }
}

Prevention

When it happens

Trigger: Page 3+ of the jobs listing returns 429 (rate limit) after pages 1-2 succeeded; token revoked between the pipeline fetch and the jobs fetch (401); a 5xx mid-listing; permissions changed mid-walk so later pages 403.

Common situations: Deep pagination against rate limits when several large pipelines are polled concurrently; long-running token expiry hitting mid-request-sequence; GitLab rolling restarts during incidents.

Related errors


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