rust-lang/rust · error · anyhow::Error
Cannot get jobs of workflow run {workflow_run_id}: {status}
Error message
Cannot get jobs of workflow run {workflow_run_id}: {status}
{} What it means
citool's GitHubClient::get_workflow_run_jobs (src/ci/citool/src/github.rs) GETs /repos/{repo}/actions/runs/{workflow_run_id}/jobs. If GitHub returns a non-success HTTP status, it returns an anyhow error listing the workflow run id, the status, and the response body. It is a network/permission/NOT-found style failure surfaced as an anyhow::Error.
Source
Thrown at src/ci/citool/src/github.rs:46
let response = body
.read_json::<WorkflowRunJobsResponse>()
.context("cannot deserialize workflow run jobs response")?;
// The CI job names have a prefix, e.g. `auto - foo`. We remove the prefix here to
// normalize the job name.
Ok(response
.jobs
.into_iter()
.map(|mut job| {
job.name = job
.name
.split_once(" - ")
.map(|res| res.1.to_string())
.unwrap_or_else(|| job.name);
job
})
.collect())
} else {
Err(anyhow::anyhow!(
"Cannot get jobs of workflow run {workflow_run_id}: {status}\n{}",
body.read_to_string()?
))
}
}
}
#[derive(serde::Deserialize)]
struct WorkflowRunJobsResponse {
jobs: Vec<GitHubJob>,
}
#[derive(serde::Deserialize)]
struct GitHubJob {
name: String,
id: u64,
}
View on GitHub (pinned to 7088e4b63a)
Solutions
- Verify the workflow_run_id is correct and belongs to the configured repo.
- Ensure GITHUB_TOKEN has actions:read on the repo and is not expired.
- Retry after a brief backoff if the body indicates a rate limit (403 with X-RateLimit-Remaining: 0) or a 5xx.
- Check the repo slug and that the run has not been deleted.
Example fix
// before
let jobs = client.get_workflow_run_jobs(repo, run_id)?; // status 404 -> error
// after: validate id and token before the call
if run_id == 0 || !token_has_scope(&token, "actions:read") {
return Err(anyhow::anyhow!("invalid run id or token scope"));
}
let jobs = retry::retry_fn(|| client.get_workflow_run_jobs(repo, run_id), 3)?; Defensive patterns
Strategy: retry
Validate before calling
// Validate inputs before calling get_workflow_run_jobs.
fn valid_run_id(id: u64) -> bool { id != 0 }
fn token_has_actions_read(token: &str) -> bool { /* check scopes */ true }
// if !valid_run_id(run_id) || !token_has_actions_read(&token) { return Err(...) } Try / catch
let jobs = match client.get_workflow_run_jobs(repo, run_id) {
Ok(j) => j,
Err(e) => {
let s = format!("{e:#}");
if s.contains("403") || s.contains("5") {
// rate limit / server error -> backoff and retry once
std::thread::sleep(std::time::Duration::from_secs(5));
client.get_workflow_run_jobs(repo, run_id)?
} else { return Err(e); }
}
}; Prevention
- Pass the correct workflow_run_id and repo slug.
- Ensure GITHUB_TOKEN has actions:read and is not expired.
- Retry with backoff on 403-rate-limit or 5xx.
- Surface the response body (already in the error) to diagnose 4xx.
When it happens
Trigger: Running citool with a workflow_run_id that does not exist, belongs to another org, or whose job list query fails auth/rate-limit (HTTP 401/403/404/5xx). The status check at github.rs:25 fails and the error is built at :46.
Common situations: Wrong workflow run id passed on the citool CLI; expired or scoped GITHUB_TOKEN; GitHub API rate limiting; transient GitHub 5xx; the repo slug is misspelled.
Related errors
- Cannot fetch metrics from {url}: {} {}
- git command failed
- duplicate job name `{job_name}` in section `{section}`
- PR job `{}` differs from corresponding Auto job `{}` in conf
- Auto job `{job}` cannot have `continue_on_error: true`. If t
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/1fa22f825117d79a.
Report an issue: GitHub.