golangci/golangci-lint · error
panic occurred: %s
Error message
panic occurred: %s
What it means
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().
Source
Thrown at pkg/lint/runner.go:167
issues = append(issues, linterIssues...)
}
return r.processLintResults(issues), lintErrors
}
func (r *Runner) runLinterSafe(ctx context.Context, lintCtx *linter.Context,
lc *linter.Config,
) (ret []*result.Issue, err error) {
defer func() {
if panicData := recover(); panicData != nil {
if pe, ok := panicData.(*errorutil.PanicError); ok {
err = fmt.Errorf("%s: %w", lc.Name(), pe)
// Don't print stacktrace from goroutines twice
r.Log.Errorf("Panic: %s: %s", pe, pe.Stack())
} else {
err = fmt.Errorf("panic occurred: %s", panicData)
r.Log.Errorf("Panic stack trace: %s", debug.Stack())
}
}
}()
issues, err := lc.Linter.Run(ctx, lintCtx)
if lc.DoesChangeTypes {
// Packages in lintCtx might be dirty due to the last analysis,
// which affects to the next analysis.
// To avoid this issue, we clear type information from the packages.
// See https://github.com/golangci/golangci-lint/pull/944.
// Currently, DoesChangeTypes is true only for `unused`.
lintCtx.ClearTypesInPackages()
}
if err != nil {
return nil, errView on GitHub (pinned to ed7a235d2d)
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
Example fix
// before (.golangci.yml)
linters:
enable-all: true
// after
linters:
enable-all: true
disable:
- bodyclose # panics on generated code in vX.Y; re-enable after upgrade Defensive patterns
Strategy: try-catch
Validate before calling
// Go: cannot pre-validate linter internals, but pin compatible toolchain/linter versions // go.mod: keep golangci-lint and its linters updated; test CI config on a small file first: // golangci-lint run ./smallpkg/...
Type guard
var pe *errorutil.PanicError
if errors.As(err, &pe) {
// linter panic: pe.Error() and pe.Stack() identify the culprit
} Try / catch
if err != nil {
var pe *errorutil.PanicError
if errors.As(err, &pe) || strings.HasPrefix(err.Error(), "panic occurred:") {
log.Printf("linter crashed; disabling it for this run: %v", err)
err = nil // degrade gracefully instead of failing the pipeline
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- can't scan file %s: %w
- makezero linter failed on file %q: %w
- unknown locale: %q
- process extra words: %w
- can't get file %s contents: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/a0998f5d7ccf74cf.
Report an issue: GitHub.