vxcontrol/pentagi · error
flow %d is not completed
Error message
flow %d is not completed
What it means
Returned by CreateAssistant when an existing flow is still in FlowStatusCreated, i.e. it was created but never actually started, so attaching an assistant to it is refused. This is an intentional domain guard, not an infrastructure failure.
Source
Thrown at backend/pkg/controller/flows.go:287
fc.flows[flowID] = fw
return nil
}
if flowID == 0 {
if err := newFlow(); err != nil {
return nil, err
}
} else if fw, ok = fc.flows[flowID]; ok {
status, err := fw.GetStatus(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get flow %d status: %w", flowID, err)
}
switch status {
case database.FlowStatusCreated:
return nil, fmt.Errorf("flow %d is not completed", flowID)
case database.FlowStatusFinished, database.FlowStatusFailed:
if err := loadFlow(); err != nil {
return nil, err
}
case database.FlowStatusRunning, database.FlowStatusWaiting:
break
default:
return nil, fmt.Errorf("flow %d is in unknown status: %s", flowID, status)
}
} else {
if err := loadFlow(); err != nil {
return nil, err
}
}
if fw == nil { // just double check, this should never happen
return nil, fmt.Errorf("unexpected error: flow %d not found", flowID)
}View on GitHub (pinned to ea665308ba)
Solutions
- Start the flow first (or create a fresh flow with flowID=0) instead of attaching an assistant to a never-started flow.
- Pick a different flowID whose status is Running/Waiting, or reuse one in Finished/Failed so it gets reloaded.
- Check why the original flow never started (look for earlier errors in backend logs).
- Delete/abandon the stuck Created flow and recreate it.
Example fix
// before ctl.CreateFlow(...) // started but errored, status stays Created ctl.CreateAssistant(ctx, userID, stuckFlowID, ...) // "flow %d is not completed" // after newAssistant, err := ctl.CreateAssistant(ctx, userID, 0, input, ...) // fresh flow
Defensive patterns
Strategy: validation
Validate before calling
// check flow status before attaching an assistant
fw, _ := ctl.GetFlow(ctx, flowID)
if fw != nil {
st, err := fw.GetStatus(ctx)
if err == nil && st == "created" {
return fmt.Errorf("flow %d never started; create a new flow", flowID)
}
} Try / catch
if _, err := ctl.CreateAssistant(...); err != nil {
if strings.Contains(err.Error(), "is not completed") {
// fall back to a fresh flow
_, err = ctl.CreateAssistant(ctx, userID, 0, input, ...)
}
} Prevention
- Always start a flow before attaching assistants to it.
- Handle partial flow-creation failures: a Created flow that errored should be discarded.
- Track flow lifecycle client-side to avoid reusing stuck IDs.
When it happens
Trigger: Calling CreateAssistant with a flowID whose worker reports FlowStatusCreated — the flow was created (e.g. via a dry-run or a flow that failed to launch) but never transitioned to Running/Waiting.
Common situations: A flow creation call partially failed earlier leaving the status at Created; client code reusing a flow ID it assumed was active; a race where the flow was created but its start call never completed.
Related errors
- flow %d has status %s: loading aborted: %w
- failed to stop flow %d: %w
- failed to finish flow %d: %w
- flow not found
- flow not found
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/a0c9a036eeccd076.
Report an issue: GitHub.