{"record":{"id":"512edf165e8095e5","repo":"vitessio/vitess","slug":"query-must-match-one-of-these-templates-s","errorCode":null,"errorMessage":"Query must match one of these templates: %s","messagePattern":"Query must match one of these templates: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/wrangler/vexec_plan.go","lineNumber":275,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif updatableColumnNames := plannerParams.updatableColumnNames; len(updatableColumnNames) > 0 {\n\t\t// if updatableColumnNames is non empty, then we must only accept changes to columns listed there\n\t\tfor _, expr := range upd.Exprs {\n\t\t\tif !expr.Name.Name.EqualsAnyString(updatableColumnNames) {\n\t\t\t\treturn nil, fmt.Errorf(\"%+v cannot be changed: %v\", expr.Name.Name, sqlparser.String(expr))\n\t\t\t}\n\t\t}\n\t}\n\tif templates := plannerParams.updateTemplates; len(templates) > 0 {\n\t\tmatch, err := vx.wr.env.Parser().QueryMatchesTemplates(vx.query, templates)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !match {\n\t\t\treturn nil, fmt.Errorf(\"Query must match one of these templates: %s\", strings.Join(templates, \"; \"))\n\t\t}\n\t}\n\tupd.Where = vx.addDefaultWheres(planner, upd.Where)\n\n\tbuf := sqlparser.NewTrackedBuffer(nil)\n\tbuf.Myprintf(\"%v\", upd)\n\n\treturn &vexecPlan{\n\t\topcode:      updateQuery,\n\t\tparsedQuery: buf.ParsedQuery(),\n\t}, nil\n}\n\n// buildDeletePlan builds a plan for a DELETE query\nfunc (vx *vexec) buildDeletePlan(ctx context.Context, planner vexecPlanner, del *sqlparser.Delete) (*vexecPlan, error) {\n\tif del.Targets != nil {\n\t\treturn nil, fmt.Errorf(\"unsupported construct: %v\", sqlparser.String(del))\n\t}","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/wrangler/vexec_plan.go#L257-L293","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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`)","Check the error's template list and conform your query's shape (columns, WHERE) to one of them","If you need unsupported updates, manipulate the vreplication stream via the proper vitess commands (MoveTables/Migrate verbs) instead","On version upgrades, re-validate any scripted VExec queries against the new template list"],"exampleFix":"// before: free-form update rejected\nvexec := \"update _vt.vreplication set state='Running', message='x' where workflow='w' and id>0\"\n// after: match allowed template\nvexec := \"update _vt.vreplication set state='Running' where id=42\"","handlingStrategy":"validation","validationCode":"ok, err := parser.QueryMatchesTemplates(vexec, plannerParams.updateTemplates)\nif err != nil {\n\treturn err\n}\nif !ok {\n\treturn fmt.Errorf(\"rewrite VExec to match allowed templates: %v\", plannerParams.updateTemplates)\n}","typeGuard":null,"tryCatchPattern":"if _, err := wr.VExec(ctx, keyspace, workflow, vexec); err != nil {\n\tif strings.Contains(err.Error(), \"Query must match one of these templates\") {\n\t\t// rewrite the UPDATE to a whitelisted form\n\t}\n\treturn err\n}","preventionTips":["Use documented VExec forms for _vt.vreplication updates","Prefer MoveTables/Migrate verbs over raw VExec for workflow control","Re-validate scripted VExec queries after vitess upgrades"],"tags":["vexec","sql","validation"],"backgroundTag":"query-template-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}