vitessio/vitess · error

Query must match one of these templates: %s

Error message

Query must match one of these templates: %s

What it means

buildUpdatePlan plans UPDATE statements for VExec using vreplication planner params that restrict updates to a fixed list of allowed query templates. If the submitted query does not match any configured update template, the planner rejects it. This is a whitelist guard ensuring VExec only runs sanctioned internal updates.

Source

Thrown at go/vt/wrangler/vexec_plan.go:275

				}
			}
		}
	}
	if updatableColumnNames := plannerParams.updatableColumnNames; len(updatableColumnNames) > 0 {
		// if updatableColumnNames is non empty, then we must only accept changes to columns listed there
		for _, expr := range upd.Exprs {
			if !expr.Name.Name.EqualsAnyString(updatableColumnNames) {
				return nil, fmt.Errorf("%+v cannot be changed: %v", expr.Name.Name, sqlparser.String(expr))
			}
		}
	}
	if templates := plannerParams.updateTemplates; len(templates) > 0 {
		match, err := vx.wr.env.Parser().QueryMatchesTemplates(vx.query, templates)
		if err != nil {
			return nil, err
		}
		if !match {
			return nil, fmt.Errorf("Query must match one of these templates: %s", strings.Join(templates, "; "))
		}
	}
	upd.Where = vx.addDefaultWheres(planner, upd.Where)

	buf := sqlparser.NewTrackedBuffer(nil)
	buf.Myprintf("%v", upd)

	return &vexecPlan{
		opcode:      updateQuery,
		parsedQuery: buf.ParsedQuery(),
	}, nil
}

// buildDeletePlan builds a plan for a DELETE query
func (vx *vexec) buildDeletePlan(ctx context.Context, planner vexecPlanner, del *sqlparser.Delete) (*vexecPlan, error) {
	if del.Targets != nil {
		return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(del))
	}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Rewrite the UPDATE to match an allowed template (use the standard VExec forms documented for _vt.vreplication, e.g. `update _vt.vreplication set state='Running' where id=N`)
  2. Check the error's template list and conform your query's shape (columns, WHERE) to one of them
  3. If you need unsupported updates, manipulate the vreplication stream via the proper vitess commands (MoveTables/Migrate verbs) instead
  4. On version upgrades, re-validate any scripted VExec queries against the new template list

Example fix

// before: free-form update rejected
vexec := "update _vt.vreplication set state='Running', message='x' where workflow='w' and id>0"
// after: match allowed template
vexec := "update _vt.vreplication set state='Running' where id=42"
Defensive patterns

Strategy: validation

Validate before calling

ok, err := parser.QueryMatchesTemplates(vexec, plannerParams.updateTemplates)
if err != nil {
	return err
}
if !ok {
	return fmt.Errorf("rewrite VExec to match allowed templates: %v", plannerParams.updateTemplates)
}

Try / catch

if _, err := wr.VExec(ctx, keyspace, workflow, vexec); err != nil {
	if strings.Contains(err.Error(), "Query must match one of these templates") {
		// rewrite the UPDATE to a whitelisted form
	}
	return err
}

Prevention

When it happens

Trigger: Running a VExec update whose SQL does not match any of plannerParams.updateTemplates — e.g. a hand-written UPDATE against _vt.vreplication with a column/where shape the template doesn't allow.

Common situations: Operators writing custom VExec UPDATEs to manipulate vreplication state (e.g. setting messages or state) with non-standard syntax; product version changed the allowed templates so previously-working queries now fail; extra columns or predicates added to the update beyond the whitelist.

Related errors


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