{"record":{"id":"60c816b633f78006","repo":"vitessio/vitess","slug":"vt13001-60c816","errorCode":"VT13001","errorMessage":"VT13001: [BUG] not supported","messagePattern":"VT13001: \\[BUG\\] not supported","errorType":"error_code","errorClass":"VitessError","httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/mirror.go","lineNumber":63,"sourceCode":"\treturn &PercentBasedMirror{\n\t\tbinaryOperator: newBinaryOp(operator, target),\n\t\tPercent:        percent,\n\t}\n}\n\n// Clone will return a copy of this operator, protected so changed to the original will not impact the clone\nfunc (m *PercentBasedMirror) Clone(inputs []Operator) Operator {\n\tcloneMirror := *m\n\tcloneMirror.SetInputs(inputs)\n\treturn &cloneMirror\n}\n\n// AddPredicate is used to push predicates. It pushed it as far down as is possible in the tree.\n// If we encounter a join and the predicate depends on both sides of the join, the predicate will be split into two parts,\n// where data is fetched from the LHS of the join to be used in the evaluation on the RHS\n// TODO: we should remove this and replace it with rewriters\nfunc (m *PercentBasedMirror) AddPredicate(*plancontext.PlanningContext, sqlparser.Expr) Operator {\n\tpanic(vterrors.VT13001(\"not supported\"))\n}\n\nfunc (m *PercentBasedMirror) AddColumn(*plancontext.PlanningContext, bool, bool, *sqlparser.AliasedExpr) int {\n\tpanic(vterrors.VT13001(\"not supported\"))\n}\n\nfunc (m *PercentBasedMirror) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int {\n\treturn m.Operator().FindCol(ctx, expr, underRoute)\n}\n\nfunc (m *PercentBasedMirror) GetColumns(ctx *plancontext.PlanningContext) []*sqlparser.AliasedExpr {\n\treturn m.Operator().GetColumns(ctx)\n}\n\nfunc (m *PercentBasedMirror) GetSelectExprs(ctx *plancontext.PlanningContext) []sqlparser.SelectExpr {\n\treturn m.Operator().GetSelectExprs(ctx)\n}\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/mirror.go#L45-L81","documentation":"VT13001 internal-bug panic thrown by PercentBasedMirror.AddPredicate. Mirror (percent-based mirroring of traffic) does not support receiving pushed-down predicates through the operator API — predicates must be handled before/around the mirror operator. Hitting it means the planner tried to push a predicate into a mirrored query, which the feature never supported.","triggerScenarios":"A query planned against a table with a percent-based mirror VSchema rule while a WHERE-clause predicate is pushed down and reaches the PercentBasedMirror operator via AddPredicate.","commonSituations":"Combining mirror rules in the VSchema with non-trivial SELECT ... WHERE queries; enabling mirroring and then upgrading Vitess so a new planner phase pushes predicates further down than before.","solutions":["Remove or narrow the mirror rule scope so it does not apply to the filtered query","Simplify or remove the WHERE predicate for mirrored queries","File a bug with the query and mirror rule; mirroring + predicate pushdown is unsupported"],"exampleFix":"// before: mirror rule matches the queried table\n\"mirror_rules\": [{\"from_table\": \"t\", \"to_table\": \"t_m\", \"percent\": 50}]\n// after: restrict mirror rule or drop the predicate path\n// remove the rule for tables queried with WHERE filters","handlingStrategy":"validation","validationCode":"// ensure no mirror rule applies to tables queried with WHERE predicates\nconst mirrored = mirrorRules.some(r => r.from_table === queriedTable);\nif (mirrored && hasWherePredicate(query)) console.warn('unsupported: mirrored query with predicate');","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Do not combine mirror rules with filtered queries","Mirror only simple point reads","Keep mirror rules narrowly scoped by table","Test mirrored queries after upgrades"],"tags":["vtgate","planbuilder","mirror","unsupported-feature"],"backgroundTag":"mirror-operator-unsupported-operation","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}