vitessio/vitess · error
[BUG] tried to replace 'Key' on 'VindexParam'
Error message
[BUG] tried to replace 'Key' on 'VindexParam'
What it means
VindexParam.Key is an identifier field that the generated rewriter cannot replace in place; its callback panics on any replacement attempt. Like other identifier fields, keys must be edited by direct assignment rather than node substitution.
Source
Thrown at go/vt/sqlparser/ast_rewrite.go:14558
func (a *application) rewriteVindexParam(parent SQLNode, node VindexParam, replacer replacerFunc) bool {
if a.pre != nil {
a.cur.replacer = replacer
a.cur.parent = parent
a.cur.node = node
kontinue := !a.pre(&a.cur)
if a.cur.revisit {
a.cur.revisit = false
return a.rewriteSQLNode(parent, a.cur.node, replacer)
}
if kontinue {
return true
}
}
if a.collectPaths {
a.cur.current.AddStep(uint16(VindexParamKey))
}
if !a.rewriteIdentifierCI(node, node.Key, func(newNode, parent SQLNode) {
panic("[BUG] tried to replace 'Key' on 'VindexParam'")
}) {
return false
}
if a.collectPaths {
a.cur.current.Pop()
}
if a.post != nil {
a.cur.replacer = replacer
a.cur.parent = parent
a.cur.node = node
if !a.post(&a.cur) {
return false
}
}
return true
}
// Function Generation Source: PtrToStructMethodView on GitHub (pinned to 01a25a7d17)
Solutions
- Edit the key by direct assignment: param.Key = sqlparser.NewColIdent(newKey) on the VindexParam node
- Return (node, false) from the rewrite callback for identifier fields
- Use a dedicated walk over VindexParams rather than the generic path rewriter for parameter renaming
- Regenerate code with `make codegen` if generated files are stale
Example fix
// before
// callback: return newKeyNode, true on VindexParam.Key
// after
func repl(node, parent sqlparser.SQLNode) (sqlparser.SQLNode, bool) {
if param, ok := node.(*sqlparser.VindexParam); ok {
param.Key = sqlparser.NewColIdent(newKey)
}
return node, false
} Defensive patterns
Strategy: validation
Validate before calling
func repl(node, parent sqlparser.SQLNode) (sqlparser.SQLNode, bool) {
if param, ok := node.(*sqlparser.VindexParam); ok {
param.Key = sqlparser.NewColIdent(newKey) // edit in place
return node, false
}
return replaceIfMatched(node)
} Try / catch
err := func() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("rewrite panicked on VindexParam.Key: %v", r)
}
}()
return sqlparser.SafeRewrite(ddl, opts, repl)
}() Prevention
- Edit VindexParam keys by direct field assignment
- Never replace identifier nodes via rewriter callbacks
- Cover CREATE/ALTER VINDEX DDL in rewriter tests
When it happens
Trigger: A rewrite callback returning a replacement node when the visited child is the Key (identifiers.ColIdent) of a *VindexParam inside a VindexDefinition.
Common situations: Rewriters that transform vindex definitions generically; DDL-rewriting tools that alter `CREATE VINDEX ... TYPE ... 'k'='v'` parameters by node replacement.
Related errors
- [BUG] tried to replace 'Name' on 'TableName'
- [BUG] tried to replace 'Qualifier' on 'TableName'
- [BUG] tried to replace 'SQLNode' on 'RootNode'
- [BUG] tried to replace 'VisitThis' on 'Visitable'
- [BUG] tried to replace 'ASTType' on 'ValueContainer'
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/9e390f670e18a2b6.
Report an issue: GitHub.