{"record":{"id":"d04773eed084e0ad","repo":"vxcontrol/pentagi","slug":"failed-to-get-flow-d-status-w","errorCode":null,"errorMessage":"failed to get flow %d status: %w","messagePattern":"failed to get flow (.+?) status: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/controller/flows.go","lineNumber":282,"sourceCode":"\n\t\tfw, err = LoadFlowWorker(ctx, flow, flowWorkerCtx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to load flow %d: %w\", flowID, err)\n\t\t}\n\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}","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/controller/flows.go#L264-L300","documentation":"Wrap in CreateAssistant when fw.GetStatus(ctx) fails for an existing in-memory flow. GetStatus reads the flow's status (via the worker/subscriber state), and a failure is wrapped with the flow ID so the caller knows which flow's status could not be read.","triggerScenarios":"CreateAssistant with a flowID present in fc.flows whose GetStatus call errors — typically the underlying DB/status read fails, or the request context is canceled before the status can be fetched.","commonSituations":"Database connectivity problems while the worker reads persisted status, request context timeout, or the worker being shut down concurrently while its state is being queried.","solutions":["Check the wrapped cause for a DB or context error and fix accordingly (DB up, longer deadline).","Confirm the flow worker is still running and not torn down mid-request.","Retry the CreateAssistant call; transient DB hiccups resolve on retry.","Verify PostgreSQL health and connection pool limits."],"exampleFix":"// before\nctx with 100ms deadline -> GetStatus times out\naw, err := ctl.CreateAssistant(shortCtx, userID, flowID, ...)\n// after\naw, err := ctl.CreateAssistant(context.WithTimeout(ctx, 10*time.Second), userID, flowID, ...)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"aw, err := ctl.CreateAssistant(ctx, userID, flowID, ...)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to get flow\") {\n        // transient DB/ctx issue: retry with backoff\n    }\n    return err\n}","preventionTips":["Use contexts with adequate deadlines for status reads.","Keep the DB healthy; status reads hit the database.","Avoid tearing down flow workers concurrently with assistant creation.","Log and alert on repeated GetStatus failures."],"tags":["go","flow-status","database","wrapped-error"],"backgroundTag":"status-read-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}