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

  1. Change the argument to a []Expr-compatible slice (element type implementing ast.Expr), or cast/collect the values as ast.Expr first.
  2. Use %v for non-Expr slices instead of %n.
  3. 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

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


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/16b93bf20aad96d7. Report an issue: GitHub.