windmill-labs/windmill · error
job not found: {}
Error message
job not found: {} What it means
A helper that resolves a job (and, for flow steps, its flow id) looks up the jobs table by id; when fetch_optional returns None it throws 'job not found: {id}'. It simply means no job with that id exists in the database (in that workspace context).
Source
Thrown at backend/windmill-api/src/jobs.rs:6072
}
Ok(job.runnable_path.unwrap_or_default())
}
/// Get the flow ID for a job. If the job is a flow, returns the job_id.
/// If the job is a step in a flow, returns the parent flow ID.
async fn get_flow_id_for_job(db: &DB, job_id: Uuid) -> error::Result<Uuid> {
// First check if the job is a flow itself (kind = 'flow' or 'flowpreview')
let job_info = sqlx::query!(
r#"
SELECT kind::text as "kind!", parent_job
FROM v2_job
WHERE id = $1
"#,
job_id
)
.fetch_optional(db)
.await?
.ok_or_else(|| anyhow::anyhow!("job not found: {}", job_id))?;
// If it's a flow job, return the job_id itself
if job_info.kind == "flow" || job_info.kind == "flowpreview" {
return Ok(job_id);
}
// Otherwise, return the parent flow ID
job_info
.parent_job
.ok_or_else(|| anyhow::anyhow!("job {} has no parent flow", job_id).into())
}
#[derive(Deserialize)]
struct CancelJob {
reason: Option<String>,
}
#[derive(Debug, Deserialize)]View on GitHub (pinned to e474e8803c)
Solutions
- Verify the job id exists via the runs list or GET /jobs/w/{id}/run
- Check you are querying the correct workspace
- Handle 404 in callers so stale ids degrade gracefully
- Adjust retention/cleanup if jobs disappear while still referenced
Example fix
// before
const job = await api.getJob(wId, '123e4567-...'); // throws if purged
// after
const job = await api.getJob(wId, id).catch(e => e.status === 404 ? null : Promise.reject(e));
if (!job) console.warn(`job ${id} no longer exists`); Defensive patterns
Strategy: try-catch
Validate before calling
// check existence first (list endpoint) to avoid a hard failure
const runs = await client.listRuns(wId, { job_id: jobId });
if (runs.length === 0) console.warn('job not found, likely purged'); Try / catch
try {
const flowId = await client.resolveJobFlow(wId, jobId);
} catch (e) {
if (new RegExp('^job not found: ' + jobId).test(e.message)) {
return null; // treat as absent, e.g. purged by retention
}
throw e;
} Prevention
- Don't hard-code job ids across environments or DB resets
- Handle 404-style 'job not found' gracefully in dashboards/automations
- Align retention/cleanup with how long you reference old runs
When it happens
Trigger: Querying the job/flow-resolution endpoint with an id that was never created, already purged, or from another workspace; the run being deleted between listing and fetching.
Common situations: Hard-coded job ids in scripts surviving DB resets between environments; retention cleanup removing runs referenced by dashboards/automations; typos or truncated UUIDs.
Related errors
- Database not found
- parent flow job not found
- App ${appPath} not found
- Failed to poll dependencies job ${jobId}: ${e?.message ?? e}
- Flow ${flowPath} not found
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/6c1e9c5dbcfdfa1d.
Report an issue: GitHub.