vitessio/vitess · error
[BUG] tried to replace 'Name' on 'TableName'
Error message
[BUG] tried to replace 'Name' on 'TableName'
What it means
Generated rewriter code for TableName.Name uses rewriteIdentifierCS, whose replacement callback panics because TableName.Name cannot be rewritten in place — replacing a column name via the path rewriter would break identifier semantics handled elsewhere (e.g. colVindex rewriting tracks identifiers separately).
Source
Thrown at go/vt/sqlparser/ast_rewrite.go:13141
func (a *application) rewriteTableName(parent SQLNode, node TableName, 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(TableNameName))
}
if !a.rewriteIdentifierCS(node, node.Name, func(newNode, parent SQLNode) {
panic("[BUG] tried to replace 'Name' on 'TableName'")
}) {
return false
}
if a.collectPaths {
a.cur.current.Pop()
a.cur.current.AddStep(uint16(TableNameQualifier))
}
if !a.rewriteIdentifierCS(node, node.Qualifier, func(newNode, parent SQLNode) {
panic("[BUG] tried to replace 'Qualifier' on 'TableName'")
}) {
return false
}
if a.collectPaths {
a.cur.current.Pop()
}
if a.post != nil {
a.cur.replacer = replacer
a.cur.parent = parentView on GitHub (pinned to 01a25a7d17)
Solutions
- Do not return replacements for identifier (ColIdent/TableIdent) fields in the rewrite callback; handle name rewriting by mutating node.Name directly before/after rewriting
- Restrict the rewrite callback to replaceable node types (expressions, table names as whole nodes)
- Use a targeted AST manipulation (sqlparser.Rewrite or manual assignment) for identifier changes
- Regenerate via `make codegen` if your local generated files are stale
Example fix
// before
func repl(node, parent sqlparser.SQLNode) (sqlparser.SQLNode, bool) {
if ident, ok := node.(sqlparser.IdentifierCS); ok {
return newIdent, true // panics on TableName.Name
}
return node, false
}
// after
func repl(node, parent sqlparser.SQLNode) (sqlparser.SQLNode, bool) {
if tbl, ok := node.(*sqlparser.TableName); ok {
tbl.Name = sqlparser.NewTableIdent(newName)
}
return node, false
} Defensive patterns
Strategy: validation
Validate before calling
func repl(node, parent sqlparser.SQLNode) (sqlparser.SQLNode, bool) {
switch node.(type) {
case sqlparser.IdentifierCS, sqlparser.IdentifierCI:
return node, false // identifiers are not replaceable
}
return replaceIfMatched(node)
} Type guard
func isReplaceableNode(node sqlparser.SQLNode) bool {
switch node.(type) {
case sqlparser.IdentifierCS, sqlparser.IdentifierCI:
return false
default:
return true
}
} Try / catch
err := func() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("rewrite panicked on identifier: %v", r)
}
}()
return sqlparser.SafeRewrite(stmt, opts, repl)
}() Prevention
- Never return replacements for IdentifierCS/IdentifierCI fields
- Rename table/column identifiers by direct field assignment
- Scope rewrite callbacks to specific node types
- Add regression tests covering statements with qualified table names
When it happens
Trigger: A custom rewriter's callback returns a replacement node when the visited child is a TableName's Name field (an identifiers.ColIdent), via astRewriteVisitor/RewriteOptions that rewrite identifier nodes.
Common situations: Rewriters that generically replace all SQLNode children including identifier fields; migrating old rewrite logic to the newer path-based rewriter; using a rewriter intended for expression nodes on whole statements.
Related errors
- [BUG] tried to replace 'Qualifier' on 'TableName'
- [BUG] tried to replace 'Key' on 'VindexParam'
- [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/9bf21b01eef803fd.
Report an issue: GitHub.