{"record":{"id":"df713b8bf7563d2a","repo":"golangci/golangci-lint","slug":"s-w-df713b","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/goanalysis/runner.go","lineNumber":313,"sourceCode":"\t\t}\n\t}\n\n\t// De-duplicate diagnostics by position (not token.Pos) to\n\t// avoid double-reporting in source files that belong to\n\t// multiple packages, such as foo and foo.test.\n\ttype key struct {\n\t\ttoken.Position\n\t\t*analysis.Analyzer\n\t\tmessage string\n\t}\n\tseen := make(map[key]bool)\n\n\textract = func(act *action) {\n\t\tif act.Err != nil {\n\t\t\tif pe, ok := act.Err.(*errorutil.PanicError); ok {\n\t\t\t\tpanic(pe)\n\t\t\t}\n\t\t\tretErrors = append(retErrors, fmt.Errorf(\"%s: %w\", act.Analyzer.Name, act.Err))\n\t\t\treturn\n\t\t}\n\n\t\tif act.IsRoot {\n\t\t\tfor _, diag := range act.Diagnostics {\n\t\t\t\t// We don't display a.Name/f.Category\n\t\t\t\t// as most users don't care.\n\n\t\t\t\tposition := GetFilePositionFor(act.Package.Fset, diag.Pos)\n\t\t\t\tfile := act.Package.Fset.File(diag.Pos)\n\n\t\t\t\tk := key{Position: position, Analyzer: act.Analyzer, message: diag.Message}\n\t\t\t\tif seen[k] {\n\t\t\t\t\tcontinue // duplicate\n\t\t\t\t}\n\t\t\t\tseen[k] = true\n\n\t\t\t\tretDiag := &Diagnostic{","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/goanalysis/runner.go#L295-L331","documentation":"In golangci-lint's analysis runner, after the golangci analysis framework executes each action, any action error is attributed to its analyzer: fmt.Errorf(\"%s: %w\", act.Analyzer.Name, act.Err). Panics are re-paniced; otherwise every analyzer failure surfaces in this wrapped form.","triggerScenarios":"An analyzer's Analyze method returns an error (e.g. nil pointer on unexpected AST/package shape, type-check info missing) — the runner collects it in retErrors during result extraction.","commonSituations":"Running analyzers over packages with type errors (missing Facts/TypesInfo), analyzers that assume generated code exists, version mismatches between golangci-lint and Go toolchain producing unexpected package graphs.","solutions":["Fix the root cause named after the analyzer name prefix in the message","Run `go vet ./...` / `go build ./...` first — many analyzer errors stem from packages that don't type-check","Clean the golangci-lint cache (`golangci-lint cache clean`) and re-run","Reproduce with the single analyzer enabled (`golangci-lint run -E <analyzer>`) and report upstream if it's a tool bug"],"exampleFix":"// before - running linters over broken package\n// go build ./... fails: undefined: Foo\n$ golangci-lint run\n// after - fix compile errors first, then lint\n$ go build ./... && golangci-lint run","handlingStrategy":"try-catch","validationCode":"// gate linting behind successful type-check\nif err := sh.Run(\"go\", \"build\", \"./...\"); err != nil {\n    return fmt.Errorf(\"skip lint: packages must type-check: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"// match analyzer-prefixed errors and isolate the analyzer\nout, err := runGolangciLint(args...)\nif err != nil && strings.Contains(out, actErrPrefix) {\n    analyzer := strings.SplitN(msg, \": \", 2)[0]\n    // rerun with -E everything except `analyzer`, or report upstream\n}\n","preventionTips":["Run `go vet ./...` in CI before golangci-lint to catch type problems early","Enable analyzers incrementally; test new analyzers on a small package first","Keep golangci-lint and Go versions paired as recommended in its docs","Clean the lint cache after major version bumps"],"tags":["golangci-lint","go","static-analysis","analyzer"],"backgroundTag":"analyzer-run-failed","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}