{"record":{"id":"a0c9a036eeccd076","repo":"vxcontrol/pentagi","slug":"flow-d-is-not-completed","errorCode":null,"errorMessage":"flow %d is not completed","messagePattern":"flow (.+?) is not completed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/controller/flows.go","lineNumber":287,"sourceCode":"\n\t\tfc.flows[flowID] = fw\n\n\t\treturn nil\n\t}\n\n\tif flowID == 0 {\n\t\tif err := newFlow(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else if fw, ok = fc.flows[flowID]; ok {\n\t\tstatus, err := fw.GetStatus(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get flow %d status: %w\", flowID, err)\n\t\t}\n\n\t\tswitch status {\n\t\tcase database.FlowStatusCreated:\n\t\t\treturn nil, fmt.Errorf(\"flow %d is not completed\", flowID)\n\t\tcase database.FlowStatusFinished, database.FlowStatusFailed:\n\t\t\tif err := loadFlow(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\tcase database.FlowStatusRunning, database.FlowStatusWaiting:\n\t\t\tbreak\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"flow %d is in unknown status: %s\", flowID, status)\n\t\t}\n\t} else {\n\t\tif err := loadFlow(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif fw == nil { // just double check, this should never happen\n\t\treturn nil, fmt.Errorf(\"unexpected error: flow %d not found\", flowID)\n\t}","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/controller/flows.go#L269-L305","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nctl.CreateFlow(...) // started but errored, status stays Created\nctl.CreateAssistant(ctx, userID, stuckFlowID, ...) // \"flow %d is not completed\"\n// after\nnewAssistant, err := ctl.CreateAssistant(ctx, userID, 0, input, ...) // fresh flow","handlingStrategy":"validation","validationCode":"// check flow status before attaching an assistant\nfw, _ := ctl.GetFlow(ctx, flowID)\nif fw != nil {\n    st, err := fw.GetStatus(ctx)\n    if err == nil && st == \"created\" {\n        return fmt.Errorf(\"flow %d never started; create a new flow\", flowID)\n    }\n}","typeGuard":null,"tryCatchPattern":"if _, err := ctl.CreateAssistant(...); err != nil {\n    if strings.Contains(err.Error(), \"is not completed\") {\n        // fall back to a fresh flow\n        _, err = ctl.CreateAssistant(ctx, userID, 0, input, ...)\n    }\n}","preventionTips":["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."],"tags":["go","flow-lifecycle","domain-guard"],"backgroundTag":"flow-not-started","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}