{"record":{"id":"3142af8f8b11025e","repo":"vitessio/vitess","slug":"vt13001-3142af","errorCode":"VT13001","errorMessage":"Swap can only be used when the second argument is an input to the first","messagePattern":"Swap can only be used when the second argument is an input to the first","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/rewriters.go","lineNumber":196,"sourceCode":"\t\t}\n\t}\n\n\tc := child.Inputs()\n\tif len(c) != 1 {\n\t\tpanic(vterrors.VT13001(\"Swap can only be used on single input operators\"))\n\t}\n\n\taInputs := slices.Clone(parent.Inputs())\n\tvar tmp Operator\n\tfor i, in := range aInputs {\n\t\tif in == child {\n\t\t\ttmp = aInputs[i]\n\t\t\taInputs[i] = c[0]\n\t\t\tbreak\n\t\t}\n\t}\n\tif tmp == nil {\n\t\tpanic(vterrors.VT13001(\"Swap can only be used when the second argument is an input to the first\"))\n\t}\n\n\tchild.SetInputs([]Operator{parent})\n\tparent.SetInputs(aInputs)\n\n\treturn child, Rewrote(message)\n}\n\nfunc bottomUp(\n\troot Operator,\n\trootID semantics.TableSet,\n\tresolveID func(Operator) semantics.TableSet,\n\trewriter VisitF,\n\tshouldVisit ShouldVisit,\n\tisRoot bool,\n) (Operator, *ApplyResult) {\n\tif shouldVisit != nil && !shouldVisit(root) {\n\t\treturn root, NoRewrite","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/rewriters.go#L178-L214","documentation":"VT13001 is an internal error code used for cases that indicate a bug in Vitess' planbuilder. The generic Swap operator rewrite asserts that when swapping a parent and child operator, the child must actually be an input of the parent; if the rewriter failed to locate the child among the parent's inputs, this internal invariant was violated.","triggerScenarios":"Calling the Swap rewriter with a (parent, child) pair where the child is not present in parent's input list — i.e. `parent.Inputs()` does not contain the child being swapped.","commonSituations":"Custom operator rewriters or new planning rules calling Swap with an operator pair whose relationship was assumed but not verified; usually surfaced during development of new Vitess planning features rather than by end users.","solutions":["Verify the child operator is actually an input of the parent before calling Swap","File a bug with the query and schema if this surfaces from a standard query","Pin/check the Vitess version — this may be a fixed planner bug"],"exampleFix":"// before\noperator.Swap(ctx, parent, child) // panics if child is not an input of parent\n// after\nif slices.Contains(parent.Inputs(), child) {\n    operator.Swap(ctx, parent, child)\n} else {\n    return parent, false // skip rewrite\n}","handlingStrategy":"validation","validationCode":"func canSwap(parent Operator, child Operator) bool {\n    return slices.Contains(parent.Inputs(), child)\n}\n// call Swap only if canSwap(parent, child)","typeGuard":"func isChildOf(parent, child Operator) bool { return slices.Contains(parent.Inputs(), child) }","tryCatchPattern":null,"preventionTips":["Always confirm the parent-child input relationship before Swap","Cover new rewriters with unit tests exercising both match and non-match paths","Treat VT13001 as a bug: include query + schema in bug reports"],"tags":["internal","planbuilder","go"],"backgroundTag":"planner-internal-invariant-violation","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}