{"record":{"id":"7b51f171128eec2f","repo":"vxcontrol/pentagi","slug":"failed-to-get-flow-primary-container-w","errorCode":null,"errorMessage":"failed to get flow primary container: %w","messagePattern":"failed to get flow primary container: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/controller/flow.go","lineNumber":341,"sourceCode":"\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)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"failed to get user\")\n\t\treturn nil, fmt.Errorf(\"failed to get user %d: %w\", flow.UserID, err)\n\t}\n\n\tctx, observation := obs.Observer.NewObservation(ctx,\n\t\tlangfuse.WithObservationTraceID(flow.TraceID.String),\n\t\tlangfuse.WithObservationTraceContext(\n\t\t\tlangfuse.WithTraceName(fmt.Sprintf(\"%s%d flow worker\", fwc.cfg.TenantLabel(), flow.ID)),\n\t\t\tlangfuse.WithTraceUserID(tenantUserID(fwc.cfg, user.Mail)),\n\t\t\tlangfuse.WithTraceTags(tenantTags(fwc.cfg, \"controller\", \"flow\")),\n\t\t\tlangfuse.WithTraceSessionID(fwc.cfg.ScopedName(fmt.Sprintf(\"flow-%d\", flow.ID))),\n\t\t\tlangfuse.WithTraceMetadata(tenantMeta(fwc.cfg, langfuse.Metadata{","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/controller/flow.go#L323-L359","documentation":"During LoadFlowWorker, the flow's primary (working) Docker container is read from the DB via GetFlowPrimaryContainer; without it the resumed worker cannot execute tools. A failure here is wrapped as 'failed to get flow primary container' with the underlying SQLC/DB cause (typically sql.ErrNoRows when no primary container row exists for the flow).","triggerScenarios":"Loading a flow marked running/waiting that has no primary container row — e.g. the container was never created before crash, was deleted from the containers table, or the primary-container query fails on a DB error.","commonSituations":"Docker container rows purged manually or by a cleanup job while the flow status stayed 'running'; crash between flow creation and container registration; FK/data mismatch after DB restores.","solutions":["Check the wrapped cause: if sql.ErrNoRows, insert/recreate a primary container record for the flow or set its status to failed so it isn't loaded.","Verify the containers table still has rows for this flow ID (SELECT * FROM containers WHERE flow_id = ?).","Ensure the code path that creates the primary container commits before the flow status is set to running.","Restore consistent DB state after any manual DB surgery or restore.","If DB connectivity is the cause, fix Postgres and restart — LoadFlows will retry at next startup."],"exampleFix":"// before\n// flow stuck 'running' but container row deleted manually\nworker, err := controller.LoadFlowWorker(ctx, flow, fwc) // fails: no primary container\n// after\n_, err := fwc.DB.GetFlowPrimaryContainer(ctx, flow.ID)\nif errors.Is(err, sql.ErrNoRows) {\n    _ = fw.SetStatus(ctx, database.FlowStatusFailed) // stop trying to load it\n    return\n}\nworker, err := controller.LoadFlowWorker(ctx, flow, fwc)","handlingStrategy":"validation","validationCode":"container, err := fwc.DB.GetFlowPrimaryContainer(ctx, flow.ID)\nif errors.Is(err, sql.ErrNoRows) {\n    // no primary container: fail the flow so it isn't retried on load\n    _ = fwc.DB.UpdateFlowStatus(ctx, database.UpdateFlowStatusParams{ID: flow.ID, Status: database.FlowStatusFailed})\n    return nil\n}","typeGuard":"func hasPrimaryContainer(ctx context.Context, db DB, flowID int64) bool {\n    _, err := db.GetFlowPrimaryContainer(ctx, flowID)\n    return err == nil\n}","tryCatchPattern":"fw, err := controller.LoadFlowWorker(ctx, flow, fwc)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to get flow primary container\") {\n        // mark flow failed so startup doesn't retry it forever\n        _ = fwc.DB.UpdateFlowStatus(ctx, database.UpdateFlowStatusParams{ID: flow.ID, Status: database.FlowStatusFailed})\n    }\n    return err\n}","preventionTips":["Commit the primary-container row before flipping flow status to running","Don't purge container rows for flows still marked running/waiting","Validate DB consistency after restores or manual cleanup"],"tags":["go","database","docker-container","flow-recovery"],"backgroundTag":"record-not-found","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}