{"record":{"id":"aaf1e6ba05def1db","repo":"vxcontrol/pentagi","slug":"flow-not-found-aaf1e6","errorCode":null,"errorMessage":"flow not found","messagePattern":"flow not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/controller/vslogs.go","lineNumber":67,"sourceCode":"\n\tflows := make([]FlowVectorStoreLogWorker, 0, len(tlc.flows))\n\tfor _, flw := range tlc.flows {\n\t\tflows = append(flows, flw)\n\t}\n\n\treturn flows, nil\n}\n\nfunc (vslc *vectorStoreLogController) GetFlowVectorStoreLog(\n\tctx context.Context,\n\tflowID int64,\n) (FlowVectorStoreLogWorker, error) {\n\tvslc.mx.Lock()\n\tdefer vslc.mx.Unlock()\n\n\tflw, ok := vslc.flows[flowID]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"flow not found\")\n\t}\n\n\treturn flw, nil\n}\n","sourceCodeStart":49,"sourceCodeEnd":72,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/controller/vslogs.go#L49-L72","documentation":"GetFlowVectorStoreLog (the controller's factory/lookup) retrieves the per-flow FlowVectorStoreLogWorker from the vslc.flows map under a mutex. If no worker is registered for the given flowID it returns \"flow not found\". Like error 210, this reflects missing in-memory registration rather than a database lookup.","triggerScenarios":"Calling the controller's GetFlowVectorStoreLog(ctx, flowID, ...) for a flow whose worker was never created (NewFlowVectorStoreLogWorker + registration never ran), was de-registered on flow completion/deletion, or after a process restart.","commonSituations":"Resuming or inspecting a finished flow after server restart; a GraphQL resolver serving a stale flow ID from a saved UI session; concurrent delete of the flow racing with a log fetch.","solutions":["Validate the flow ID is an active flow before requesting its vector-store log worker.","Re-register/rebuild the flow worker lazily when the flow exists in the DB but not in memory.","Return a typed sentinel (ErrFlowNotFound) so callers can distinguish not-found from internal errors.","For flows that must be inspectable post-restart, read logs directly from the DB instead of requiring the in-memory worker."],"exampleFix":"// before\nworker, err := vslc.GetFlowVectorStoreLog(ctx, flowID, pub)\nif err != nil { return err }\n// after\nworker, err := vslc.GetFlowVectorStoreLog(ctx, flowID, pub)\nif err != nil {\n    if errors.Is(err, ErrFlowNotFound) {\n        // flow finished or server restarted: query logs directly from DB\n        return vslc.db.GetFlowVectorStoreLogs(ctx, flowID)\n    }\n    return err\n}","handlingStrategy":"fallback","validationCode":"if flowID <= 0 {\n    return fmt.Errorf(\"invalid flow id %d\", flowID)\n}\nactive, _ := isFlowActive(ctx, flowID)\nif !active {\n    // read logs directly from DB instead of requesting the in-memory worker\n    return readVectorStoreLogsFromDB(ctx, flowID)\n}","typeGuard":"func isControllerFlowNotFound(err error) bool {\n    return errors.Is(err, ErrFlowNotFound) // after introducing the sentinel\n}","tryCatchPattern":"worker, err := vslc.GetFlowVectorStoreLog(ctx, flowID, pub)\nif err != nil {\n    if errors.Is(err, ErrFlowNotFound) {\n        return fallbackDBLogReader(ctx, flowID) // finished flow or restart\n    }\n    return err\n}","preventionTips":["Introduce a sentinel ErrFlowNotFound so callers can branch on error identity.","Fall back to direct DB reads for completed/historical flows.","Re-register workers lazily when a flow exists in DB but not in memory.","Avoid holding flow IDs in client sessions across server restarts."],"tags":["go","flow-not-found","in-memory-state","controller"],"backgroundTag":"resource-not-found","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}