golangci/golangci-lint · error
failed prerequisites: %w
Error message
failed prerequisites: %w
What it means
The go-analysis runner checks each action's dependencies before running it. If any dependency action finished with an error, those errors are joined (errors.Join of unwrapped dep errors) and stored as the current action's error prefixed with 'failed prerequisites:'. The action itself never executes.
Source
Thrown at pkg/goanalysis/runner_checker.go:98
// In parallel mode, due to GC/scheduler contention, the
// time is 5x higher than in sequential mode, even with a
// semaphore limiting the number of threads here.
// So use -debug=tp.
t0 := time.Now()
defer func() {
act.Duration = time.Since(t0)
analyzeDebugf("go/analysis: %s: %s: analyzed package %q in %s", act.runner.prefix, act.Analyzer.Name, act.Package.Name, time.Since(t0))
}()
// Report an error if any dependency failures.
var depErrors error
for _, dep := range act.Deps {
if dep.Err != nil {
depErrors = errors.Join(depErrors, errors.Unwrap(dep.Err))
}
}
if depErrors != nil {
act.Err = fmt.Errorf("failed prerequisites: %w", depErrors)
return
}
// Plumb the output values of the dependencies
// into the inputs of this action. Also facts.
inputs := make(map[*analysis.Analyzer]any)
act.objectFacts = make(map[objectFactKey]analysis.Fact)
act.packageFacts = make(map[packageFactKey]analysis.Fact)
for _, dep := range act.Deps {
if dep.Package == act.Package {
// Same package, different analysis (horizontal edge):
// in-memory outputs of prerequisite analyzers
// become inputs to this analysis pass.
inputs[dep.Analyzer] = dep.Result
} else if dep.Analyzer == act.Analyzer { // (always true)
// Same analysis, different package (vertical edge):
// serialized facts produced by prerequisite analysisView on GitHub (pinned to ed7a235d2d)
Solutions
- Look below the 'failed prerequisites:' prefix — the joined dependency errors name the real root cause; fix that first
- Ensure the analyzed packages type-check (`go build ./...`) before linting
- Run with fewer analyzers to isolate which dependency chain fails
- Clean the analysis cache and retry to rule out a corrupted action cache
Example fix
// before - analyzing packages with type errors // pkg/a.go: undefined: Missing $ golangci-lint run ./... // failed prerequisites: ... (cascade) // after - fix the dependency error first $ go build ./... # fix pkg/a.go $ golangci-lint run ./...
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure all deps type-check before running dependent analyzers
if err := sh.Run("go", "build", "./..."); err != nil {
return err // prevents cascading 'failed prerequisites'
} Try / catch
// when using the analysis framework directly
if err := pass.Run(...); err != nil {
if strings.HasPrefix(err.Error(), "failed prerequisites:") {
cause := errors.Unwrap(err) // joined dep errors; log and fix root
}
return err
} Prevention
- Always read the joined error detail under the prefix — it names the root failing action
- Fix upstream analyzer errors before debugging dependents
- Ensure packages compile and type information loads before analysis
- Use errors.Join-aware logging so multi-cause failures are fully printed
When it happens
Trigger: Analyzer A depends on analyzer B's facts/results; B's action errored (e.g. B panicked or returned an error), so every dependent action A is marked failed with this message.
Common situations: Cascading failures after one root analyzer error (see runner.go extraction); packages that fail type-checking so fact-producing analyzers (buildtag, stdmethods, etc.) error first; mixed analyzer versions where a required fact is never produced.
Related errors
- %s: %w
- can't load config: %w
- can't get enabled linters: %w
- failed to read go.mod: %w
- failed to compute go.sum: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/623cef3c811712be.
Report an issue: GitHub.