vitessio/vitess · critical
[BUG] tried to replace 'ASTType' on 'ValueContainer'
Error message
[BUG] tried to replace 'ASTType' on 'ValueContainer'
What it means
This panic lives inside the generated AST rewriter for the ValueContainer node. The 'ASTType' child of a ValueContainer is structural and must never be rewritten, so the rewrite callback is written to panic '[BUG] tried to replace ASTType on ValueContainer' if the walker ever proposes replacing it. Hitting it means an invariant of the AST rewriting contract is violated — it is always a bug in the rewriter/walker, not in user code.
Source
Thrown at go/tools/asthelpergen/integration/ast_rewrite.go:450
func (a *application) rewriteValueContainer(parent AST, node ValueContainer, 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.rewriteAST(parent, a.cur.node, replacer)
}
if kontinue {
return true
}
}
if a.collectPaths {
a.cur.current.AddStep(uint16(ValueContainerASTType))
}
if !a.rewriteAST(node, node.ASTType, func(newNode, parent AST) {
panic("[BUG] tried to replace 'ASTType' on 'ValueContainer'")
}) {
return false
}
if a.collectPaths {
a.cur.current.Pop()
a.cur.current.AddStep(uint16(ValueContainerASTImplementationType))
}
if !a.rewriteRefOfLeaf(node, node.ASTImplementationType, func(newNode, parent AST) {
panic("[BUG] tried to replace 'ASTImplementationType' on 'ValueContainer'")
}) {
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
- Inspect the rewrite pass stack trace to find which walker change proposes replacing the ASTType child
- Fix the rewrite callback/walker so ASTType children are skipped (not visited as replaceable) and re-run make codegen
- Report upstream if it reproduces on unmodified vitess main — it indicates a codegen bug in asthelpergen rewrite generation
Defensive patterns
Strategy: try-catch
Validate before calling
// Reproduce under test with path collection enabled before merging walker changes
node.Rewrite(func(newNode, parent AST) { ... }) // run in a test with collectPaths = true Try / catch
func() {
defer func() {
if r := recover(); r != nil && strings.Contains(fmt.Sprint(r), "tried to replace 'ASTType'") {
log.Fatalf("codegen bug: rewriter touched ASTType child: %v", r)
}
}()
runRewritePass(node)
}() Prevention
- Never modify ASTType children in rewrite callbacks — only value/implementation children
- Re-run make codegen and sqlparser tests after any AST definition change
- Treat this panic as a bug report: capture the stack trace and fix the walker, don't work around it in caller code
When it happens
Trigger: Running a rewrite pass (rewriteAST) over a ValueContainer node where the replacement logic tries to substitute the node's ASTType child instead of its value or implementation-type children; typically caused by changes to the generated walker or rewrite rules.
Common situations: After regenerating sqlparser code (make codegen) following an AST definition change, rewrite passes on type-valued containers start crashing in tests.
Related errors
- unknown ASTStep
- [BUG] tried to replace 'SQLNode' on 'RootNode'
- [BUG] tried to replace 'Name' on 'TableName'
- [BUG] tried to replace 'Qualifier' on 'TableName'
- [BUG] tried to replace 'Key' on 'VindexParam'
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/d84deac2ac36389a.
Report an issue: GitHub.