{"record":{"id":"1d45e0913aa0a9ce","repo":"golangci/golangci-lint","slug":"printing-s-w","errorCode":null,"errorMessage":"printing %s: %w","messagePattern":"printing (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/internal/migrate/cloner/cloner.go","lineNumber":176,"sourceCode":"\tif key == \",squash\" {\n\t\treturn wrapStructTag(`yaml:\",inline\"`)\n\t}\n\n\treturn wrapStructTag(fmt.Sprintf(`yaml:\"%[1]s,omitempty\" toml:\"%[1]s,multiline,omitempty\"`, key))\n}\n\nfunc wrapStructTag(s string) string {\n\treturn \"`\" + s + \"`\"\n}\n\nfunc writeNewFile(fset *token.FileSet, file *ast.File, srcPath, dstDir string) error {\n\tvar buf bytes.Buffer\n\n\tbuf.WriteString(\"// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT.\\n\\n\")\n\n\terr := printer.Fprint(&buf, fset, file)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"printing %s: %w\", srcPath, err)\n\t}\n\n\tdstPath := filepath.Join(dstDir, filepath.Base(srcPath))\n\n\t_ = os.MkdirAll(filepath.Dir(dstPath), os.ModePerm)\n\n\tformatted, err := imports.Process(dstPath, buf.Bytes(), nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"formatting %s: %w\", dstPath, err)\n\t}\n\n\t//nolint:gosec,mnd // The permission is right.\n\terr = os.WriteFile(dstPath, formatted, 0o644)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"writing file %s: %w\", dstPath, err)\n\t}\n\n\treturn nil","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/internal/migrate/cloner/cloner.go#L158-L194","documentation":"writeNewFile serializes the transformed AST back to text with printer.Fprint. The 'printing %s: %w' wrap means the go/printer failed to emit the AST. This is rare — go/printer only errors on internal problems like an AST node with invalid positions or malformed comments — and typically points to a bug in the AST mutation done by processFile/processStructFields.","triggerScenarios":"writeNewFile is called (from the processPackage walk callback) after processFile mutated the AST, and printer.Fprint returns an error, usually because hand-constructed or mutated AST nodes carry inconsistent position info (e.g. a StarExpr wrapping an ident whose Pos is invalid after field manipulation).","commonSituations":"Extending the cloner's AST transformations (convertType, processStructFields) with manually built nodes lacking valid positions; corrupted comment positions in the source file can also trip the printer.","solutions":["Look at the wrapped printer error to identify which node/position is invalid","Verify any hand-constructed ast nodes (e.g. StarExpr in convertType) reuse positions from the original expression rather than token.NoPos where possible","Run gofmt on the source file to rule out unusual formatting/comment edge cases","Simplify the AST mutation, or re-derive nodes with ast.NewIdent / copied positions, then re-run the cloner"],"exampleFix":"// before\nreturn &ast.StarExpr{X: ident}\n// after (preserve source position so the printer can emit valid output)\nreturn &ast.StarExpr{Star: ident.Pos(), X: ident}","handlingStrategy":"try-catch","validationCode":"// pre-check: print the mutated AST to a buffer and gofmt-validate before writing\nvar pre bytes.Buffer\nif err := printer.Fprint(&pre, fset, file); err != nil {\n    return fmt.Errorf(\"printing %s: %w\", srcPath, err)\n}\nif _, err := format.Source(pre.Bytes()); err != nil {\n    return fmt.Errorf(\"printed AST invalid for %s: %w\", srcPath, err)\n}","typeGuard":null,"tryCatchPattern":"if err := writeNewFile(fset, file, srcPath, dstDir); err != nil {\n    if strings.Contains(err.Error(), \"printing \") {\n        log.Printf(\"printer failed for %s: %v — inspect AST mutations\", srcPath, err)\n    }\n    return err\n}","preventionTips":["When building AST nodes manually, copy positions from the original nodes","Avoid token.NoPos on synthesized nodes where possible","Test transformations on files containing comments and multi-line declarations","Keep AST mutation logic (processFile) minimal and reviewed"],"tags":["go","ast","printer","code-generation"],"backgroundTag":"ast-print-failed","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}