{"record":{"id":"ecb397c055c166bd","repo":"vxcontrol/pentagi","slug":"flow-not-found-ecb397","errorCode":null,"errorMessage":"flow not found","messagePattern":"flow not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/controller/tclogs.go","lineNumber":67,"sourceCode":"\n\tflows := make([]FlowToolCallLogWorker, 0, len(c.flows))\n\tfor _, flw := range c.flows {\n\t\tflows = append(flows, flw)\n\t}\n\n\treturn flows, nil\n}\n\nfunc (c *toolCallLogController) GetFlowToolCallLog(\n\tctx context.Context,\n\tflowID int64,\n) (FlowToolCallLogWorker, error) {\n\tc.mx.Lock()\n\tdefer c.mx.Unlock()\n\n\tflw, ok := c.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/tclogs.go#L49-L72","documentation":"GetFlowToolCallLog looks up the per-flow FlowToolCallLogWorker in an in-memory map keyed by flowID. This error means no worker has been registered for that flow ID — it is a pure lookup miss, not a database error. The worker is created when a flow is instantiated, so asking before creation (or after process restart / flow removal) yields this error.","triggerScenarios":"Calling GetFlowToolCallLog with a flowID that was never created, a flow already finished/removed from the map, or after a backend restart while clients still hold old flow IDs.","commonSituations":"Stale IDs in a frontend after server redeploy; racing a flow-creation request with tool-call queries; querying flows created by another instance in multi-node deployments.","solutions":["Verify the flow exists and was created through the normal flow-creation API before querying its log worker","Check errors.Is equivalent (string match \"flow not found\") and map to 404 in handlers","Re-query the flow list instead of reusing cached flow IDs after restarts","If running multiple instances, ensure requests are routed to the node owning the flow (or persist worker state externally)","Create the worker via the controller's flow-registration path if you legitimately need one"],"exampleFix":"// before\nworker, err := ctl.GetFlowToolCallLog(ctx, flowID) // panics downstream on nil use\nif err != nil { return err } // treated as 500\n// after\nworker, err := ctl.GetFlowToolCallLog(ctx, flowID)\nif err != nil && strings.Contains(err.Error(), \"flow not found\") {\n    return graphql.ErrorNotFound // or HTTP 404\n}","handlingStrategy":"type-guard","validationCode":"func flowKnown(flowID int64, knownFlows map[int64]struct{}) bool {\n    _, ok := knownFlows[flowID]\n    return ok\n}","typeGuard":"func isFlowNotFound(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"flow not found\")\n}","tryCatchPattern":"worker, err := ctl.GetFlowToolCallLog(ctx, flowID)\nif isFlowNotFound(err) {\n    return nil, httpErr(http.StatusNotFound, \"flow %d not found\", flowID)\n}\nif err != nil {\n    return nil, err\n}","preventionTips":["Create flows through the controller API before touching their workers","Invalidate cached flow IDs after any backend restart","Route requests for a flow to the instance that created it in multi-node setups","Treat this as a client error (404), never retry it","Clean up workers on flow completion to keep the map authoritative"],"tags":["not-found","flow","lookup"],"backgroundTag":"resource-not-found","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}