vxcontrol/pentagi · error

failed to bulk-update flows provider name: %w

Error message

failed to bulk-update flows provider name: %w

What it means

Raised inside reassignFlowsProvider (used by RenameFlowsProvider and ResetFlowsProviderToDefault) when the bulk UPDATE of the flows table — UpdateFlowsProviderNameByOldName — fails while repointing all of a user's flows from oldName to newName after a custom provider rename. The SQL error is logged and wrapped as "failed to bulk-update flows provider name: %w". The function then still attempts the assistants update and joins errors, so a flows-only failure does not skip the second table.

Source

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

	if _, err := fc.provs.GetProvider(ctx, oldName, userID); err == nil {
		logger.Debug("old provider name still resolves, nothing to reassign")
		return nil
	}

	// Detached from the caller's request context: these are two short statements
	// and the reference must not be left half-rewritten because a browser tab
	// was closed. The timeout keeps a stuck DB from pinning the goroutine.
	ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), reassignProviderTimeout)
	defer cancel()

	flows, flowsErr := fc.db.UpdateFlowsProviderNameByOldName(ctx, database.UpdateFlowsProviderNameByOldNameParams{
		NewName: newName.String(),
		UserID:  userID,
		OldName: oldName.String(),
	})
	if flowsErr != nil {
		logger.WithError(flowsErr).Error("failed to bulk-update flows provider name")
		flowsErr = fmt.Errorf("failed to bulk-update flows provider name: %w", flowsErr)
	}

	assistants, asstErr := fc.db.UpdateAssistantsProviderNameByOldName(
		ctx, database.UpdateAssistantsProviderNameByOldNameParams{
			NewName: newName.String(),
			UserID:  userID,
			OldName: oldName.String(),
		})
	if asstErr != nil {
		logger.WithError(asstErr).Error("failed to bulk-update assistants provider name")
		asstErr = fmt.Errorf("failed to bulk-update assistants provider name: %w", asstErr)
	}

	// Publishing happens only after both writes are done. A subscriber that is
	// not draining its channel makes each publish cost up to the subscription
	// send timeout, so doing it in between would let a wedged websocket client
	// eat the deadline and starve the second UPDATE.
	for _, flow := range flows {

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check server logs — the underlying SQL error is logged with logger.WithError before wrapping.
  2. Verify PostgreSQL health and retry the rename; the sweeps only match rows still bearing oldName, making the operation idempotent.
  3. Check for lock contention on the flows table (e.g. other long-running transactions).
  4. Confirm the update completes within reassignProviderTimeout; tune the timeout if the DB is slow.

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

// verify provider names differ before triggering a cascade
if oldName == newName {
    return nil // reassignFlowsProvider no-ops here anyway
}

Type guard

null

Try / catch

if err := flows.RenameFlowsProvider(ctx, userID, old, new); err != nil {
    if strings.Contains(err.Error(), "failed to bulk-update flows provider name") {
        // idempotent: only rows still bearing oldName are rewritten
        time.Sleep(backoff)
        err = flows.RenameFlowsProvider(ctx, userID, old, new)
    }
    return err
}

Prevention

When it happens

Trigger: Calling RenameFlowsProvider or ResetFlowsProviderToDefault for a user whose old provider name no longer resolves, when the UPDATE flows SET ... WHERE user_id=? AND provider_name=oldName query fails: DB unreachable, lock contention/timeout, or the detached 30s reassignProviderTimeout context expires.

Common situations: PostgreSQL overloaded or under lock contention during a provider rename from the settings UI; slow/failing DB causing context deadline; network blip between backend and database mid-rename; stale connection pool after a DB failover.

Related errors


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