vitessio/vitess · error
slow path for `n` directive for slice of type other than Exp
Error message
slow path for `n` directive for slice of type other than Expr
What it means
The %n directive has a fast path for slices whose element type implements ast.Expr, which the generator knows how to emit. A slice of any other element type has no implemented code path, so the tool panics explicitly rather than generating incorrect output — this is a deliberate 'not implemented' guard.
Source
Thrown at go/tools/astfmtgen/main.go:269
inputExpr := expr.Args[2+fieldnum]
inputType := r.pkg.TypesInfo.Types[inputExpr].Type
sliceType, ok := inputType.(*types.Slice)
if !ok {
panic("'%n' directive requires a slice")
}
if types.Implements(sliceType.Elem(), r.astExpr) {
// Fast path: input is []Expr
call := &ast.CallExpr{
Fun: &ast.SelectorExpr{
X: callexpr.X,
Sel: &ast.Ident{Name: "formatExprs"},
},
Args: []ast.Expr{inputExpr},
}
cursor.InsertBefore(&ast.ExprStmt{X: call})
break
}
panic("slow path for `n` directive for slice of type other than Expr")
default:
panic(fmt.Sprintf("unsupported escape %q", token))
}
fieldnum++
i++
}
cursor.Delete()
return true
}
var noQualifier = func(p *types.Package) string {
return ""
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Change the argument to a []Expr-compatible slice (element type implementing ast.Expr), or cast/collect the values as ast.Expr first.
- Use %v for non-Expr slices instead of %n.
- If Expr-slice support is genuinely required, extend rewriteAstPrintf in go/tools/astfmtgen/main.go to emit the slow path.
Example fix
// before ast_sprintf(body, "%n", body.Stmts) // []ast.Stmt: panics // after ast_sprintf(body, "%v", body.Stmts)
Defensive patterns
Strategy: fallback
Validate before calling
// before using %n, confirm the element type implements ast.Expr
elem := sliceType.Elem()
if !types.Implements(elem, exprInterfaceType) {
// fall back to %v instead of %n
} Prevention
- Treat %n as strictly 'slice of ast.Expr'; use %v for []ast.Stmt, []*ast.Field, etc.
- Convert other node-kind slices to []ast.Expr only when the elements truly implement ast.Expr.
- Extend astfmtgen deliberately (with tests) before introducing new %n element types.
When it happens
Trigger: A %n directive's argument is a slice, but its element type does not implement ast.Expr, e.g. []ast.Stmt, []*ast.Field, or []string passed to ast_sprintf with %n.
Common situations: Assuming %n works for any node slice (it only supports ast.Expr implementations); refactoring a field from []ast.Expr to another node-kind slice while keeping the %n verb; adding a new AST node kind slice without extending astfmtgen.
Related errors
- bad literal argument
- '%n' directive requires a slice
- package '%s' does not contain 'ast_format.go'
- generator failed for type %s: %w
- unsupported pointer type %T
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/16b93bf20aad96d7.
Report an issue: GitHub.