{"record":{"id":"a0998f5d7ccf74cf","repo":"golangci/golangci-lint","slug":"panic-occurred-s","errorCode":null,"errorMessage":"panic occurred: %s","messagePattern":"panic occurred: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/lint/runner.go","lineNumber":167,"sourceCode":"\n\t\tissues = append(issues, linterIssues...)\n\t}\n\n\treturn r.processLintResults(issues), lintErrors\n}\n\nfunc (r *Runner) runLinterSafe(ctx context.Context, lintCtx *linter.Context,\n\tlc *linter.Config,\n) (ret []*result.Issue, err error) {\n\tdefer func() {\n\t\tif panicData := recover(); panicData != nil {\n\t\t\tif pe, ok := panicData.(*errorutil.PanicError); ok {\n\t\t\t\terr = fmt.Errorf(\"%s: %w\", lc.Name(), pe)\n\n\t\t\t\t// Don't print stacktrace from goroutines twice\n\t\t\t\tr.Log.Errorf(\"Panic: %s: %s\", pe, pe.Stack())\n\t\t\t} else {\n\t\t\t\terr = fmt.Errorf(\"panic occurred: %s\", panicData)\n\t\t\t\tr.Log.Errorf(\"Panic stack trace: %s\", debug.Stack())\n\t\t\t}\n\t\t}\n\t}()\n\n\tissues, err := lc.Linter.Run(ctx, lintCtx)\n\n\tif lc.DoesChangeTypes {\n\t\t// Packages in lintCtx might be dirty due to the last analysis,\n\t\t// which affects to the next analysis.\n\t\t// To avoid this issue, we clear type information from the packages.\n\t\t// See https://github.com/golangci/golangci-lint/pull/944.\n\t\t// Currently, DoesChangeTypes is true only for `unused`.\n\t\tlintCtx.ClearTypesInPackages()\n\t}\n\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/lint/runner.go#L149-L185","documentation":"golangci-lint recovers panics raised inside individual linters so one crashing linter does not abort the whole run. If the recovered value is not an errorutil.PanicError (i.e. a non-error value like a string or runtime error not wrapped by the library), the runner wraps it as a plain 'panic occurred: %s' error attributed to the linter name, and logs the goroutine stack via debug.Stack().","triggerScenarios":"A linter's Run(ctx, lintCtx) panics with a raw non-PanicError value (e.g. nil map write, index out of range, panic(\"...\"), panic(someString)) and the deferred recover in runLinter catches it, producing this error for that linter's result.","commonSituations":"Bugs in third-party/custom linters, linters incompatible with the Go version being analyzed, pathological input files (generated code, generics edge cases), out-of-memory-driven runtime panics during analysis.","solutions":["Identify the linter from the wrapped message or log line 'Panic stack trace' and report/upgrade it (go.mod update or golangci-lint upgrade often fixes known linter panics)","Disable the offending linter in .golangci.yml (linters.disable) or skip the triggering file via exclusions until fixed","Run with --fix=false and a minimal reproduction file, then file an issue against the linter/golangci-lint with the stack trace","Pin a golangci-lint version known to work with your Go toolchain version"],"exampleFix":"// before (.golangci.yml)\nlinters:\n  enable-all: true\n// after\nlinters:\n  enable-all: true\n  disable:\n    - bodyclose # panics on generated code in vX.Y; re-enable after upgrade","handlingStrategy":"try-catch","validationCode":"// Go: cannot pre-validate linter internals, but pin compatible toolchain/linter versions\n// go.mod: keep golangci-lint and its linters updated; test CI config on a small file first:\n// golangci-lint run ./smallpkg/...","typeGuard":"var pe *errorutil.PanicError\nif errors.As(err, &pe) {\n\t// linter panic: pe.Error() and pe.Stack() identify the culprit\n}","tryCatchPattern":"if err != nil {\n\tvar pe *errorutil.PanicError\n\tif errors.As(err, &pe) || strings.HasPrefix(err.Error(), \"panic occurred:\") {\n\t\tlog.Printf(\"linter crashed; disabling it for this run: %v\", err)\n\t\terr = nil // degrade gracefully instead of failing the pipeline\n\t}\n}","preventionTips":["Keep golangci-lint and all linters at versions compatible with your Go toolchain","Run linters on a minimal target first when adopting new linters or Go releases","Capture the 'Panic stack trace' log line and file an upstream issue instead of retrying blindly","Exclude known-crashing linters or generated files via .golangci.yml exclusions"],"tags":["panic","linter","recovery","runtime"],"backgroundTag":"panic-recovered-in-linter","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}