micro/go-micro · error
run %s is waiting at unknown step %q
Error message
run %s is waiting at unknown step %q
What it means
ResumeWith resumes a run waiting for input by marking the awaited step done and advancing. If the run's persisted State.Stage doesn't match any step in the flow's current Steps configuration (stepIndex < 0), the library cannot identify which step the input satisfies and returns this error. It almost always means the flow definition and the persisted run state have drifted apart.
Source
Thrown at flow/steps.go:529
return err
}
if f.checkpoint == nil {
return fmt.Errorf("flow %s has no checkpoint configured", f.name)
}
run, ok, err := f.checkpoint.Load(ctx, runID)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("run %s not found", runID)
}
if run.Status != "waiting" {
return fmt.Errorf("run %s is not waiting for input (status %q)", runID, run.Status)
}
steps := f.opts.Steps
i := stepIndex(steps, run.State.Stage)
if i < 0 {
return fmt.Errorf("run %s is waiting at unknown step %q", runID, run.State.Stage)
}
// The awaited step is satisfied by the injected input; record it done and
// advance so runFrom re-enters at the next step.
run.Steps[i].Status = "done"
run.Steps[i].Result = truncate(input, 200)
run.State.Data = []byte(input)
if i+1 < len(steps) {
run.State.Stage = steps[i+1].Name
} else {
run.State.Stage = ""
}
run.Await = nil
run.Status = "running"
_, err = f.runFrom(ctx, run)
return err
}
// runFrom executes steps from the run's current Stage to the end,View on GitHub (pinned to 24529f1404)
Solutions
- Restore the persisted step name in the flow's Steps so State.Stage matches again.
- Migrate the stale run: update run.State.Stage in the checkpoint store to a valid step name, or expire the run.
- Version flows (distinct flow names/checkpoint keys per definition version) so old runs resume against their matching definition.
- Drain all waiting runs via ResumeWith before deploying step renames or deletions.
Example fix
// before (deployed rename)
flow.Steps(flow.Step{Name: "review-v2", Run: review}) // runs wait at "review"
// after (keep original name)
flow.Steps(flow.Step{Name: "review", Run: review}) Defensive patterns
Strategy: validation
Validate before calling
run, _, err := ckpt.Load(ctx, runID)
if err == nil && stepIndex(f.opts.Steps, run.State.Stage) < 0 {
return fmt.Errorf("run %s waits at unknown step %q; cannot inject input", runID, run.State.Stage)
} Type guard
func stageKnown(steps []flow.Step, stage string) bool { return stepIndex(steps, stage) >= 0 } Try / catch
if _, err := f.ResumeWith(ctx, runID, input); err != nil {
if strings.Contains(err.Error(), "waiting at unknown step") {
// stale run from an old flow definition; expire or migrate it
return expireRun(ctx, runID)
}
return err
} Prevention
- Freeze step names once flows are live; add new steps instead of renaming
- Version flow definitions so waiting runs resume against their own schema
- Alert on 'unknown step' errors — they signal definition/run state drift
- Drain waiting runs before deploys that alter step names
When it happens
Trigger: Calling flow.ResumeWith(ctx, runID, input) where run.State.Stage names a step absent from f.opts.Steps — the step was renamed/removed in a deploy, or the run was created by a differently configured flow sharing the same checkpoint store.
Common situations: Deploying a new flow version with renamed steps while waiting runs persist across restarts; resuming a run with a different Flow instance than the one that started it; multiple flow definitions writing to one checkpoint store without namespacing.
Related errors
- run %s is not waiting for input (status %q)
- agent resume: unsupported agent implementation %T
- LLM step requires a flow model (set Provider/APIKey)
- flow %s has no checkpoint configured
- run %s not found
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/c73aa267cd95a6d2.
Report an issue: GitHub.