{"record":{"id":"ac067989595fed0e","repo":"rust-lang/rust","slug":"job-name-not-found-the-following-jobs-are-avail","errorCode":null,"errorMessage":"Job {name} not found. The following jobs are available:\n{}","messagePattern":"Job (.+?) not found\\. The following jobs are available:\n(.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/ci/citool/src/jobs.rs","lineNumber":407,"sourceCode":"        RunType::MainJob => \"main\",\n    };\n\n    eprintln!(\"Output\");\n    eprintln!(\"jobs={jobs:?}\");\n    eprintln!(\"run_type={run_type}\");\n    println!(\"jobs={}\", serde_json::to_string(&jobs)?);\n    println!(\"run_type={run_type}\");\n\n    Ok(())\n}\n\npub fn find_linux_job<'a>(jobs: &'a [Job], name: &str) -> anyhow::Result<&'a Job> {\n    let Some(job) = jobs.iter().find(|j| j.name == name) else {\n        let available_jobs: Vec<&Job> = jobs.iter().filter(|j| j.is_linux()).collect();\n        let mut available_jobs =\n            available_jobs.iter().map(|j| j.name.to_string()).collect::<Vec<_>>();\n        available_jobs.sort();\n        return Err(anyhow::anyhow!(\n            \"Job {name} not found. The following jobs are available:\\n{}\",\n            available_jobs.join(\", \")\n        ));\n    };\n    if !job.is_linux() {\n        return Err(anyhow::anyhow!(\"Only Linux jobs can be executed locally\"));\n    }\n\n    Ok(job)\n}\n","sourceCodeStart":389,"sourceCodeEnd":418,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/src/ci/citool/src/jobs.rs#L389-L418","documentation":"Thrown by find_linux_job when no job in the provided slice has a name equal to the requested name. It then lists all jobs whose os field contains 'ubuntu' (the Linux-executable jobs), sorted alphabetically, so the caller can correct the name. This is the local-execution lookup path.","triggerScenarios":"Calling run-workflow-locally (or find_linux_job directly) with a job name that does not exactly match any Job.name in the pr_jobs or auto_jobs slice; passing a display name instead of the canonical name; casing or suffix mismatch (e.g. omitting -alt).","commonSituations":"Typo in the job name on the command line; the job exists only in optional_jobs (which local execution does not search); the job name changed in jobs.yml but the caller used the old name.","solutions":["Read the list of available jobs printed in the error message and copy the exact name.","Confirm the job is in the pr or auto bucket (find_linux_job only receives one of those slices), not optional_jobs.","Check jobs.yml for the canonical name, including any -alt suffix."],"exampleFix":"// before\n$ citool local --job dist-x86_64-linux\nError: Job dist-x86_64-linux not found. The following jobs are available:\ndist-x86_64-linux-alt, dist-x86_64-unknown-linux-gnu, ...\n\n// after\n$ citool local --job dist-x86_64-unknown-linux-gnu","handlingStrategy":"validation","validationCode":"// Before calling find_linux_job, confirm the name exists in the slice.\nlet exists = jobs.iter().any(|j| j.name == name);\nif !exists {\n    eprintln!(\"Job '{name}' not in list. Available: {:?}\",\n        jobs.iter().map(|j| j.name.as_str()).collect::<Vec<_>>());\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"match jobs::find_linux_job(jobs, &name) {\n    Ok(job) => { /* proceed */ }\n    Err(e) => {\n        // e already lists available Linux jobs; surface and exit gracefully\n        eprintln!(\"{e:#}\");\n        std::process::exit(2);\n    }\n}","preventionTips":["Copy job names verbatim from jobs.yml rather than typing them.","Prefer glob expansion in try-job patterns over guessing exact names.","Remember local execution only searches pr_jobs or auto_jobs, not optional_jobs."],"tags":["ci","citool","job-matrix","local-execution"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}