{"record":{"id":"445af34284955e22","repo":"vitessio/vitess","slug":"package-s-does-not-contain-ast-format-go","errorCode":null,"errorMessage":"package '%s' does not contain 'ast_format.go'","messagePattern":"package '(.+?)' does not contain 'ast_format\\.go'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/tools/astfmtgen/main.go","lineNumber":90,"sourceCode":"\t}\n}\n\ntype Rewriter struct {\n\tpkg     *packages.Package\n\tastExpr *types.Interface\n\tastfmt  int\n}\n\nvar printerConfig = printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}\n\nfunc NewRewriter(pkg *packages.Package) (*Rewriter, error) {\n\tscope := pkg.Types.Scope()\n\texprT := scope.Lookup(\"Expr\").(*types.TypeName)\n\texprN := exprT.Type().(*types.Named).Underlying()\n\n\tastfmt := slices.IndexFunc(pkg.GoFiles, func(f string) bool { return path.Base(f) == \"ast_format.go\" })\n\tif astfmt < 0 {\n\t\treturn nil, fmt.Errorf(\"package '%s' does not contain 'ast_format.go'\", pkg.Name)\n\t}\n\n\treturn &Rewriter{\n\t\tpkg:     pkg,\n\t\tastExpr: exprN.(*types.Interface),\n\t\tastfmt:  astfmt,\n\t}, nil\n}\n\nfunc (r *Rewriter) Rewrite() error {\n\tfile := r.pkg.GoFiles[r.astfmt]\n\tsyntax := r.pkg.Syntax[r.astfmt]\n\n\t// Add fmt import since %d is handled by calling fmt.Sprintf(\"%d\",...)\n\tastutil.AddImport(r.pkg.Fset, syntax, \"fmt\")\n\tastutil.Apply(syntax, r.replaceAstfmtCalls, nil)\n\n\tdirname, _ := path.Split(file)","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/tools/astfmtgen/main.go#L72-L108","documentation":"NewRewriter in the astfmtgen code-generation tool loads the target package, extracts the Expr interface, and requires the package to contain a file literally named ast_format.go; if none of the package's Go files has that base name it returns this error. The tool needs that file because the generated walker/writer code is keyed to it.","triggerScenarios":"Running astfmtgen against a package directory whose sources lack ast_format.go (wrong package path argument, or a package that was restructured/renamed its format file).","commonSituations":"Passing go/vt/sqlparser-adjacent packages by mistake; refactors renaming ast_format.go; running the tool on a freshly scaffolded package that never had the file.","solutions":["Invoke the tool on the correct package (go/vt/sqlparser), which contains ast_format.go","Restore/rename the file to ast_format.go if a refactor changed its name","Check pkg.GoFiles in the error context to confirm which package was actually loaded"],"exampleFix":"// before\nastfmtgen -i vitess.io/vitess/go/vt/sqlparser/ast_clone_pkg // no ast_format.go\n// after\nastfmtgen -i vitess.io/vitess/go/vt/sqlparser // contains ast_format.go","handlingStrategy":"validation","validationCode":"func packageHasAstFormat(dir string) bool {\n\t_, err := os.Stat(filepath.Join(dir, \"ast_format.go\"))\n\treturn err == nil\n}","typeGuard":null,"tryCatchPattern":"rw, err := NewRewriter(pkgPath)\nif err != nil {\n\tif strings.Contains(err.Error(), \"does not contain 'ast_format.go'\") {\n\t\treturn fmt.Errorf(\"wrong package for astfmtgen: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Run astfmtgen only on packages that own an ast_format.go (currently go/vt/sqlparser)","Add a Makefile precheck that verifies ast_format.go exists before codegen","Keep ast_format.go's name stable across refactors or update the tool in the same PR"],"tags":["go","codegen","tools","astfmtgen"],"backgroundTag":"missing-required-source-file","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}