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
- Ensure you reference the flow job id, not a child script/step id
- Re-run the flow; the run's internal state is unusable
- Check Windmill version/upgrade path if old runs consistently lack flow_status
- 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
- Use the flow job id, never a step/script id, for flow-level routes
- Don't hand-edit jobs rows; let the engine write flow_status
- Keep deployments consistent so old runs aren't read with new schemas
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
- Flow ${flowPath} not found
- job not found or parent flow not in queue: {}
- parent flow job not found
- unable to find the module
- App ${appPath} not found
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/627cc7ddf6597c6e.
Report an issue: GitHub.