{"record":{"id":"43241c1abb10b281","repo":"vitessio/vitess","slug":"vt09015-43241c","errorCode":"VT09015","errorMessage":"VT09015: schema tracking required","messagePattern":"VT09015: schema tracking required","errorType":"error_code","errorClass":"VitessError","httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/phases.go","lineNumber":149,"sourceCode":"}\n\nfunc findDMLAboveRoute(ctx *plancontext.PlanningContext, root Operator) Operator {\n\tvisitor := func(in Operator, _ semantics.TableSet, isRoot bool) (Operator, *ApplyResult) {\n\t\tswitch op := in.(type) {\n\t\tcase *Delete:\n\t\t\treturn createDMLWithInput(ctx, op, op.Source, op.DMLCommon)\n\t\tcase *Update:\n\t\t\treturn createDMLWithInput(ctx, op, op.Source, op.DMLCommon)\n\t\t}\n\t\treturn in, NoRewrite\n\t}\n\n\treturn BottomUp(root, TableID, visitor, stopAtRoute)\n}\n\nfunc createDMLWithInput(ctx *plancontext.PlanningContext, op, src Operator, in *DMLCommon) (Operator, *ApplyResult) {\n\tif len(in.Target.VTable.PrimaryKey) == 0 {\n\t\tpanic(vterrors.VT09015())\n\t}\n\tdm := &DMLWithInput{}\n\tleftComp := make(sqlparser.ValTuple, 0, len(in.Target.VTable.PrimaryKey))\n\tproj := newAliasedProjection(src)\n\tdm.cols = make([][]*sqlparser.ColName, 1)\n\tfor _, col := range in.Target.VTable.PrimaryKey {\n\t\tcolName := sqlparser.NewColNameWithQualifier(col.String(), in.Target.Name)\n\t\tctx.SemTable.Recursive[colName] = in.Target.ID\n\t\tproj.AddColumn(ctx, true, false, aeWrap(colName))\n\t\tdm.cols[0] = append(dm.cols[0], colName)\n\t\tleftComp = append(leftComp, colName)\n\t}\n\n\tdm.Source = proj\n\n\tvar targetTable *Table\n\t_ = Visit(src, func(operator Operator) error {\n\t\tif tbl, ok := operator.(*Table); ok && tbl.QTable != nil && tbl.QTable.ID == in.Target.ID {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/phases.go#L131-L167","documentation":"VT09015 signals that the planned DML (UPDATE/DELETE executed via DMLWithInput) requires schema tracking in vtgate. When the target table's primary key is unknown — because schema tracking is disabled, vtgate never learned the table's PrimaryKey — the planner cannot build the input-based DML and raises this error instead. It is a configuration/feature-availability error, not a bug.","triggerScenarios":"Executing an UPDATE or DELETE that is expanded to DML-with-input (e.g. DML through a view or on a table needing the input-based plan) while the target VTable has no PrimaryKey recorded because vtgate was started without schema tracking enabled.","commonSituations":"Deployments with default vtgate flags running such DMLs; enabling views/DML-with-input features without turning on schema tracking; tables defined without a primary key in MySQL, so even with tracking there is no key to use.","solutions":["Start vtgate with schema tracking enabled (--schema_change_signal-enabled / the schema-tracking flag for your release) so the planner can learn table primary keys","Ensure the target table actually has a PRIMARY KEY defined in MySQL","If schema tracking cannot be enabled, rewrite the DML to a form not requiring input-based execution","Check the release notes/flags for your Vitess version, as the enabling flag naming has changed across versions"],"exampleFix":"// before: vtgate started without schema tracking\nvtgate --topo_implementation etcd2 ...\n// after\nvtgate --topo_implementation etcd2 --schema_change_signal_enabled ...","handlingStrategy":"validation","validationCode":"// check before issuing DML that requires input-based execution\nif (!vtgateFlags.schemaTrackingEnabled) {\n  throw new Error('enable schema tracking on vtgate before running this DML');\n}\n// and confirm the table has a primary key\nSHOW CREATE TABLE target_table; -- must contain a PRIMARY KEY","typeGuard":"null","tryCatchPattern":"try {\n  await vtgate.execute(session, dml, bindVars);\n} catch (e) {\n  if (String(e.message).includes('VT09015')) {\n    // restart/enable schema tracking or rewrite the DML\n  }\n  throw e;\n}","preventionTips":["Enable schema tracking flags on vtgate in environments running complex DML","Define PRIMARY KEY on every DML target table","Verify flags after upgrades (flag names change across releases)","Avoid DML-through-view patterns unless schema tracking is on"],"tags":["vtgate","dml","schema-tracking","configuration"],"backgroundTag":"schema-tracking-required","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}