{"record":{"id":"ae3ae0f48336af4e","repo":"vxcontrol/pentagi","slug":"flow-d-has-status-s-loading-aborted-w","errorCode":null,"errorMessage":"flow %d has status %s: loading aborted: %w","messagePattern":"flow (.+?) has status (.+?): loading aborted: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"backend/pkg/controller/flow.go","lineNumber":328,"sourceCode":"\tif !fwc.dryRun {\n\t\tif err := fw.PutInput(ctx, fwc.input, nil, fwc.resources); err != nil {\n\t\t\treturn nil, wrapErrorEndSpan(ctx, flowSpan, \"failed to run flow worker\", err)\n\t\t}\n\t}\n\n\tflowSpan.End(langfuse.WithSpanStatus(\"flow worker started\"))\n\n\treturn fw, nil\n}\n\nfunc LoadFlowWorker(ctx context.Context, flow database.Flow, fwc flowWorkerCtx) (FlowWorker, error) {\n\tctx, span := obs.Observer.NewSpan(ctx, obs.SpanKindInternal, \"controller.LoadFlowWorker\")\n\tdefer span.End()\n\n\tswitch flow.Status {\n\tcase database.FlowStatusRunning, database.FlowStatusWaiting:\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"flow %d has status %s: loading aborted: %w\", flow.ID, flow.Status, ErrNothingToLoad)\n\t}\n\n\tlogger := logrus.WithContext(ctx).WithFields(logrus.Fields{\n\t\t\"flow_id\":       flow.ID,\n\t\t\"user_id\":       flow.UserID,\n\t\t\"provider_name\": flow.ModelProviderName,\n\t\t\"provider_type\": flow.ModelProviderType,\n\t})\n\n\tcontainer, err := fwc.db.GetFlowPrimaryContainer(ctx, flow.ID)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"failed to get flow primary container\")\n\t\treturn nil, fmt.Errorf(\"failed to get flow primary container: %w\", err)\n\t}\n\n\tlogger.Info(\"flow loaded from DB\")\n\n\tuser, err := fwc.db.GetUser(ctx, flow.UserID)","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/controller/flow.go#L310-L346","documentation":"LoadFlowWorker resurrects flow workers at startup (LoadFlows) for flows persisted as running. Only FlowStatusRunning and FlowStatusWaiting qualify; any other persisted status (created, finished, failed, completed) is not loadable, so it wraps ErrNothingToLoad with the flow's ID and actual status. This is an expected skip, not a corruption signal.","triggerScenarios":"LoadFlows iterates flows after server restart and calls LoadFlowWorker on a flow whose stored status is not Running/Waiting — e.g. it finished, failed, or was created but never started before the crash.","commonSituations":"Server restart with flows left in FlowStatusFailed/Finished/Completed from a previous run; crash mid-flow leaving status 'created'; manually flipping status in DB to test and forgetting to set it back to running/waiting.","solutions":["Only treat this as a problem if the flow should be resumable: set its status to FlowStatusRunning or FlowStatusWaiting in the DB.","If the flow is genuinely done, ignore/retry-skip: the loader will skip non-running flows.","Check why the flow ended in an unexpected status (worker crash logs for that flow ID).","Filter the flows query in LoadFlows to statuses Running/Waiting to avoid noisy errors for finished flows."],"exampleFix":"// before\nfor _, flow := range flows {\n    fw, err := controller.LoadFlowWorker(ctx, flow, fwc)\n    if err != nil { log.WithError(err).Error(\"load failed\") }\n}\n// after\nfor _, flow := range flows {\n    if flow.Status != database.FlowStatusRunning && flow.Status != database.FlowStatusWaiting {\n        continue // skip terminal/created flows, matches ErrNothingToLoad guard\n    }\n    fw, err := controller.LoadFlowWorker(ctx, flow, fwc)\n    if err != nil { log.WithError(err).Error(\"load failed\") }\n}","handlingStrategy":"validation","validationCode":"if flow.Status != database.FlowStatusRunning && flow.Status != database.FlowStatusWaiting {\n    // skip: only running/waiting flows are loadable\n    return nil\n}","typeGuard":"func isLoadable(s database.FlowStatus) bool {\n    return s == database.FlowStatusRunning || s == database.FlowStatusWaiting\n}","tryCatchPattern":"fw, err := controller.LoadFlowWorker(ctx, flow, fwc)\nif err != nil {\n    if errors.Is(err, controller.ErrNothingToLoad) {\n        log.Infof(\"flow %d in status %s: nothing to load, skipping\", flow.ID, flow.Status)\n        return nil\n    }\n    return err\n}","preventionTips":["Pre-filter flows by status Running/Waiting in the loader query","Check errors.Is(err, ErrNothingToLoad) and skip rather than fail startup","Investigate flows unexpectedly left in non-loadable statuses after crashes"],"tags":["go","flow-lifecycle","state-machine","startup-recovery"],"backgroundTag":"invalid-state-transition","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}