vitessio/vitess · error

validateWorkflowName.VReplicationExec: <dynamic…

Error message

validateWorkflowName.VReplicationExec: <dynamic validation.msg from workflow validation query>

What it means

During workflow-name validation, wrangler ran a validation query against the primary tablet via VReplicationExec and either the query failed or it returned rows, meaning the workflow name/state fails validation. The recorded message wraps either the query error or the dynamic validation.msg describing the problem found. It indicates a workflow in the keyspace does not satisfy the expected invariants (e.g. unexpected state or stale streams).

Solutions

  1. Read the inner validation.msg in the wrapped error to see exactly which query/condition failed
  2. Inspect _vt.vreplication rows on the primary tablet (mysql -e 'select * from _vt.vreplication') and remove stale entries
  3. Fix the underlying VReplicationExec failure (tablet connectivity, permissions) if the error is a query error
  4. Re-run the validation command after cleanup

Example fix

-- inspect and clean stale streams
SELECT workflow, id FROM _vt.vreplication WHERE db_name='vt_ks';
DELETE FROM _vt.vreplication WHERE workflow='<bad>' AND workflow_state='Cancelled';
Defensive patterns

Strategy: try-catch

Validate before calling

-- pre-check the primary's vreplication state yourself
SELECT workflow, workflow_state FROM _vt.vreplication WHERE db_name='vt_<ks>';

Try / catch

if err := wr.validateWorkflowName(ctx, keyspace); err != nil {
	var allErr error
	// unwrap to find inner validation.msg or VReplicationExec failure
	log.Printf("workflow validation failed: %v", err)
	return err
}

Prevention

When it happens

Trigger: Calling keyspace validation (e.g. vtctldclient ValidateWorkflowName / Keyspace validation paths in wrangler) while a validation.query on the primary tablet returns rows signaling an invalid workflow name condition.

Common situations: Stale or manually created rows in _vt.vreplication conflicting with the workflow name; validation run before/after a partially completed MoveTables; version mismatches where the tablet's schema for _vt tables differs.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/9a5341925d6fccc2. Report an issue: GitHub.

Appendix: source

Thrown at go/vt/wrangler/keyspace.go:85

			validations := []struct {
				query string
				msg   string
			}{{
				fmt.Sprintf("select 1 from _vt.vreplication where db_name=%s and workflow=%s", encodeString(primary.DbName()), encodeString(workflow)),
				fmt.Sprintf("workflow %s already exists in keyspace %s on tablet %d", workflow, keyspace, primary.Alias.Uid),
			}, {
				fmt.Sprintf("select 1 from _vt.vreplication where db_name=%s and message='FROZEN' and workflow_sub_type != %d", encodeString(primary.DbName()), binlogdatapb.VReplicationWorkflowSubType_Partial),
				fmt.Sprintf("found previous frozen workflow on tablet %d, please review and delete it first before creating a new workflow",
					primary.Alias.Uid),
			}}
			for _, validation := range validations {
				p3qr, err := wr.tmc.VReplicationExec(ctx, primary.Tablet, validation.query)
				if err != nil {
					allErrors.RecordError(vterrors.Wrap(err, "validateWorkflowName.VReplicationExec"))
					return
				}
				if p3qr != nil && len(p3qr.Rows) != 0 {
					allErrors.RecordError(vterrors.Wrap(errors.New(validation.msg), "validateWorkflowName.VReplicationExec"))
					return
				}
			}
		}(si)
	}
	wg.Wait()
	return allErrors.AggrError(vterrors.Aggregate)
}

// refreshPrimaryTablets will just RPC-ping all the primary tablets with RefreshState
func (wr *Wrangler) refreshPrimaryTablets(ctx context.Context, shards []*topo.ShardInfo) error {
	wg := sync.WaitGroup{}
	rec := concurrency.AllErrorRecorder{}
	for _, si := range shards {
		wg.Add(1)
		go func(si *topo.ShardInfo) {
			defer wg.Done()
			wr.Logger().Infof("RefreshState primary %v", topoproto.TabletAliasString(si.PrimaryAlias))

View on GitHub (pinned to 01a25a7d17)