windmill-labs/windmill · error

unable to find the flow status in the flow job

Error message

unable to find the flow status in the flow job

What it means

The flow job's flow_status JSON column is expected to contain the current FlowStatus (module states); this error fires when flow.flow_status() returns None — the job exists but carries no flow status payload. Only flow jobs should reach this code path, so a missing status means corrupt or absent internal state.

Source

Thrown at backend/windmill-api/src/jobs.rs:5515

    // The resume secret is this route's gate, so it never reaches
    // `require_job_read_access` and the run-scope confinement that gate carries. Re-apply
    // it against the flow whose args and status are about to be returned: holding a
    // resume secret must not let a scoped token read a flow it may not run. Anonymous
    // approvers are unaffected.
    if let Some(authed) = authed.as_ref() {
        require_job_within_run_scope(&db, authed, &w_id, &flow_id).await?;
    }

    let flow = GetQuery::new()
        .without_logs()
        .without_code()
        .fetch(&db, &flow_id, &w_id)
        .await?;

    let flow_status = flow
        .flow_status()
        .ok_or_else(|| anyhow::anyhow!("unable to find the flow status in the flow job"))?;
    let flow_module_status = flow_status
        .modules
        .iter()
        .find(|p| p.job() == Some(job))
        .ok_or_else(|| anyhow::anyhow!("unable to find the module"))?;

    let trigger_email = match &flow {
        Job::CompletedJob(job) => &job.email,
        Job::QueuedJob(job) => &job.email,
    };
    conditionally_require_authed_user(
        authed.clone(),
        flow_status.approval_conditions.clone(),
        trigger_email,
    )?;

    let approvers_from_status = match flow_module_status {
        FlowStatusModule::Success { approvers, .. } => approvers.to_owned(),

View on GitHub (pinned to e474e8803c)

Solutions

  1. Ensure you reference the flow job id, not a child script/step id
  2. Re-run the flow; the run's internal state is unusable
  3. Check Windmill version/upgrade path if old runs consistently lack flow_status
  4. Inspect the jobs row's flow_status column to confirm it is valid JSON

Example fix

// before
getApprovalPage(wId, stepJobId) // step id has no flow_status
// after
getApprovalPage(wId, flowJobId) // the flow run's own id
Defensive patterns

Strategy: validation

Validate before calling

// ensure the id refers to a flow job before hitting approval endpoints
const run = await client.getJobRun(wId, jobId);
if (run.kind !== 'flow') throw new Error('not a flow job: no flow status');

Type guard

function isFlowJob(run) {
  return run != null && (run.kind === 'flow' || run.kind === 'flowpreview');
}

Prevention

When it happens

Trigger: Calling the approval page/status endpoint for a job whose flow_status column is null or unparsable — e.g. a non-flow job id passed to the route, or a run created before status was written.

Common situations: Passing a script/job id instead of the flow job id; runs from very old Windmill versions with a different flow_status schema; DB rows edited or partially migrated.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/627cc7ddf6597c6e. Report an issue: GitHub.