vxcontrol/pentagi · warning

flow not found

Error message

flow not found

What it means

GetFlowMsgLog returns the in-memory message-log worker registered for a flow. The controller keeps workers in a map keyed by flow ID; if the ID is absent (map miss), it returns a plain error "flow not found". This is a lookup miss on runtime state, not a database query — only flows with an active, loaded msg-log worker can be retrieved.

Source

Thrown at backend/pkg/controller/msglogs.go:64

func (mlc *msgLogController) ListFlowsMsgLog(ctx context.Context) ([]FlowMsgLogWorker, error) {
	mlc.mx.Lock()
	defer mlc.mx.Unlock()

	flows := make([]FlowMsgLogWorker, 0, len(mlc.flows))
	for _, flw := range mlc.flows {
		flows = append(flows, flw)
	}

	return flows, nil
}

func (mlc *msgLogController) GetFlowMsgLog(ctx context.Context, flowID int64) (FlowMsgLogWorker, error) {
	mlc.mx.Lock()
	defer mlc.mx.Unlock()

	flw, ok := mlc.flows[flowID]
	if !ok {
		return nil, fmt.Errorf("flow not found")
	}

	return flw, nil
}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check that the flow ID is correct and the flow is currently active.
  2. Distinguish this error from ErrFlowNotFound handling — it is a plain fmt.Errorf, so compare by string or add a sentinel if you need programmatic checks.
  3. Fetch message logs from the database for finished flows instead of the in-memory worker.
  4. After a backend restart, reload the flow list before querying per-flow workers.

Example fix

// before: treating any error as transient
flw, err := msgLogs.GetFlowMsgLog(ctx, flowID)

// after: handle the not-found case explicitly
flw, err := msgLogs.GetFlowMsgLog(ctx, flowID)
if err != nil {
    if strings.Contains(err.Error(), "flow not found") {
        // fall back to persisted msg logs or return 404 to the client
        return nil, ErrFlowNotFound
    }
    return nil, err
}
Defensive patterns

Strategy: type-guard

Validate before calling

// only query workers for flows you know are currently loaded
active, err := flows.ListFlows(ctx)
if err != nil {
    return err
}
// ensure flowID is among active flows before calling GetFlowMsgLog

Type guard

func isFlowNotFoundError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "flow not found")
}

Try / catch

flw, err := msgLogs.GetFlowMsgLog(ctx, flowID)
if err != nil {
    if isFlowNotFoundError(err) {
        return nil, ErrFlowNotFound // map to 404 upstream
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling MsgLogController.GetFlowMsgLog(ctx, flowID) with a flowID that was never registered (no flow worker started), a flow that already finished and was removed from the map, or a backend restart (workers are in-memory only and not rehydrated for this controller).

Common situations: Client requesting message logs for a closed/finished flow; stale flow ID cached in the UI after a backend restart; race where the flow finished between listing and fetching; using a flow ID from a different environment/database.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/5cf177637c833080. Report an issue: GitHub.