vxcontrol/pentagi · error

failed to renew flow %d status: %w

Error message

failed to renew flow %d status: %w

What it means

Wrap inside the loadFlow closure of CreateAssistant. Before reloading a flow worker, the controller resets the flow's status to FlowStatusWaiting via db.UpdateFlowStatus; if that DB update fails the error is wrapped with the flow ID so callers know which flow could not be renewed.

Source

Thrown at backend/pkg/controller/flows.go:262

		})
		if err != nil {
			return fmt.Errorf("failed to create flow worker: %w", err)
		}

		fc.flows[fw.GetFlowID()] = fw
		flowID = fw.GetFlowID()
		fw.SetStatus(ctx, database.FlowStatusWaiting)

		return nil
	}

	loadFlow := func() error {
		flow, err := fc.db.UpdateFlowStatus(ctx, database.UpdateFlowStatusParams{
			ID:     flowID,
			Status: database.FlowStatusWaiting,
		})
		if err != nil {
			return fmt.Errorf("failed to renew flow %d status: %w", flowID, err)
		}

		fw, err = LoadFlowWorker(ctx, flow, flowWorkerCtx)
		if err != nil {
			return fmt.Errorf("failed to load flow %d: %w", flowID, err)
		}

		fc.flows[flowID] = fw

		return nil
	}

	if flowID == 0 {
		if err := newFlow(); err != nil {
			return nil, err
		}
	} else if fw, ok = fc.flows[flowID]; ok {
		status, err := fw.GetStatus(ctx)

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check PostgreSQL availability and backend logs for the underlying driver error.
  2. Verify the flow row with that ID still exists (it may have been deleted while in-memory state was stale).
  3. Increase the request/database timeout; a canceled ctx aborts the UPDATE.
  4. Run pending goose migrations so the flow status enum/columns match the code.
  5. Retry CreateAssistant once the database is healthy.

Example fix

// before
flow row deleted externally -> UpdateFlowStatus returns 0 rows/error
// after
recreate the flow (flowID=0) or restore the row; e.g.
SELECT id FROM flows WHERE id = :flowID; -- confirm existence before reusing the ID
Defensive patterns

Strategy: retry

Validate before calling

// verify the flow row still exists before reusing the ID
var n int
err := db.QueryRowContext(ctx, `SELECT count(*) FROM flows WHERE id = $1`, flowID).Scan(&n)
if err != nil || n == 0 { return fmt.Errorf("flow %d no longer exists", flowID) }

Try / catch

if err := loadFlow(); err != nil {
    if isTransientDBError(errors.Unwrap(err)) {
        time.Sleep(backoff); retry once
    }
    return err
}

Prevention

When it happens

Trigger: CreateAssistant with an existing flowID whose status is Finished/Failed (or which is not in the in-memory map), and the UpdateFlowStatus SQL call fails — DB down, connection pool exhausted, row for flowID deleted, context canceled/deadline exceeded.

Common situations: PostgreSQL restart or network blip mid-request, the flow row was removed while workers still reference it, migration drift leaving status enum values missing, or the request context timing out before the UPDATE completes.

Related errors


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