golangci/golangci-lint · error
can't run linter %s
Error message
can't run linter %s
What it means
Runner.Run executes each enabled linter via runLinterSafe inside a timed stage tracker. If a linter returns an error (not a panic), Run joins it into a joined error with the message "can't run linter <name>" and continues with the remaining linters. Linting overall continues; the failure is reported at the end.
Source
Thrown at pkg/lint/runner.go:144
Log: log,
}, nil
}
func (r *Runner) Run(ctx context.Context, linters []*linter.Config) ([]*result.Issue, error) {
sw := timeutils.NewStopwatch("linters", r.Log)
defer sw.Print()
var (
lintErrors error
issues []*result.Issue
)
for _, lc := range linters {
linterIssues, err := timeutils.TrackStage(sw, lc.Name(), func() ([]*result.Issue, error) {
return r.runLinterSafe(ctx, r.lintCtx, lc)
})
if err != nil {
lintErrors = errors.Join(lintErrors, fmt.Errorf("can't run linter %s", lc.Linter.Name()), err)
r.Log.Warnf("Can't run linter %s: %v", lc.Linter.Name(), err)
continue
}
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)View on GitHub (pinned to ed7a235d2d)
Solutions
- Check the accompanying Warnf log "Can't run linter <name>: <err>" for the underlying cause
- Run golangci-lint with `-v` to see per-linter stage output and isolate the failing linter
- Run the failing linter alone (`golangci-lint run --enable-only <name>`) to reproduce and fix its specific issue
- Increase `run.timeout`, or exclude problematic files/dirs via `linters.exclusions.rules` if a specific file triggers the failure
Example fix
// before (.golangci.yml) run: timeout: 1m # large repo exceeds this // after run: timeout: 10m
Defensive patterns
Strategy: try-catch
Validate before calling
// Isolate the failing linter before a full run: // golangci-lint run --enable-only <name> ./... // go vet ./... # many runtime linter failures mirror vet/parse errors
Try / catch
lintErrors, err := runLinterSafe(ctx, lintCtx, lc)
if err != nil {
var joined interface{ Unwrap() []error }
if errors.As(err, &joined) {
for _, e := range errors.Unwrap(err).([]error) {
log.Warnf("linter failed: %v", e) // handle per-linter cause
}
}
continue // Run() already continues to next linter
} Prevention
- Set a realistic `run.timeout` for your repo size
- Exclude generated/vendored files via `linters.exclusions.paths` to avoid pathological inputs
- Upgrade golangci-lint regularly so bundled linters match your code's Go version
- Run linters individually in CI when bisecting a failure
When it happens
Trigger: Any non-panic error returned from a linter's analysis pass in runLinterSafe: analyzer reporting fatal diagnostics, linter failing to parse invalid Go syntax, running out of memory/timeout for huge packages, or a linter's internal dependency failing on the given codebase.
Common situations: Linter choking on generated or malformed code; timeout (`run.timeout`) hitting on large repos; a newly updated linter version incompatible with the codebase; linter requiring CGO while CGO_ENABLED=0.
Related errors
- %s: %w
- the configuration contains invalid elements
- unsupported configuration format
- the configuration contains invalid elements
- parallel golangci-lint is running
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/d3e07c5617be4ce5.
Report an issue: GitHub.