Problem
580 occurrences of fmt.Errorf(...) without the %w verb were found in non-test production code across 173 files, versus 1004 occurrences that correctly use %w. This means roughly 37% of error wrapping discards the original error and breaks errors.Is / errors.As lookup chains.
High-concentration files include:
pkg/parser/schedule_fuzzy_scatter.go — 31 instances without %w
pkg/workflow/stop_after.go — 16 instances without %w
pkg/workflow/compiler_pre_activation_job.go — 10 instances without %w
pkg/workflow/call_workflow_validation.go — 9 instances without %w
pkg/workflow/engine_validation.go — 17 instances without %w
Example from pkg/workflow/call_workflow_validation.go:
// Without %w — caller cannot use errors.Is(err, someTargetErr)
return fmt.Errorf("call workflow: unsupported trigger %q", trigger)
Impact
- Severity: High
- Affected Files: 173 production files
- Risk: Loss of error context and inability to type-assert or sentinel-check errors upstream; harder to diagnose production failures
Recommendation
For errors that wrap an underlying err, add %w:
Before:
return fmt.Errorf("failed to parse schedule: %s", err)
After:
return fmt.Errorf("failed to parse schedule: %w", err)
For errors with no underlying cause to wrap, fmt.Errorf without %w is intentional and correct — only wrap when an err variable is being included.
A focused sweep of the high-count files listed above would address the majority of cases.
Validation
Estimated Effort: Medium (mechanical but requires careful review to avoid wrapping non-error strings)
Generated by Sergo - Serena Go Expert · ● 536.8K · ◷
Problem
580 occurrences of
fmt.Errorf(...)without the%wverb were found in non-test production code across 173 files, versus 1004 occurrences that correctly use%w. This means roughly 37% of error wrapping discards the original error and breakserrors.Is/errors.Aslookup chains.High-concentration files include:
pkg/parser/schedule_fuzzy_scatter.go— 31 instances without%wpkg/workflow/stop_after.go— 16 instances without%wpkg/workflow/compiler_pre_activation_job.go— 10 instances without%wpkg/workflow/call_workflow_validation.go— 9 instances without%wpkg/workflow/engine_validation.go— 17 instances without%wExample from
pkg/workflow/call_workflow_validation.go:Impact
Recommendation
For errors that wrap an underlying
err, add%w:Before:
After:
For errors with no underlying cause to wrap,
fmt.Errorfwithout%wis intentional and correct — only wrap when anerrvariable is being included.A focused sweep of the high-count files listed above would address the majority of cases.
Validation
go vet ./...— it warns onfmt.Errorfwith%swhen an error is presentgolangci-lintrulewrapcheckorerrorlintto catch future occurrencesgrep -n 'fmt.Errorf.*%s.*err' pkg/to surface remaining candidateserrors.Is/Astests still pass after migrationEstimated Effort: Medium (mechanical but requires careful review to avoid wrapping non-error strings)