Skip to content

fix: use %w instead of %v/%s in fmt.Errorf to preserve error chains - #3730

Merged
sebrandon1 merged 1 commit into
redhat-best-practices-for-k8s:mainfrom
sebrandon1:fix/error-wrapping-preserve-chains
Jun 17, 2026
Merged

fix: use %w instead of %v/%s in fmt.Errorf to preserve error chains#3730
sebrandon1 merged 1 commit into
redhat-best-practices-for-k8s:mainfrom
sebrandon1:fix/error-wrapping-preserve-chains

Conversation

@sebrandon1

@sebrandon1 sebrandon1 commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

  • Replace %v and %s with %w in 199 fmt.Errorf call sites across 50 files where the argument is an error value
  • Preserves error chains so callers can use errors.Is() and errors.As() to inspect wrapped errors (Go blog: Working with Errors in Go 1.13)
  • Update 3 test files that compared errors by type (assert.Equal(t, errors.New(...))) to use assert.EqualError instead

How is this different than prior attempts?

This repo has had two prior error-handling PRs that addressed a different problem:

PR What it fixed Scope
#3627 Bare return err — added context where there was none 13 files, ~13 wraps
#3633 Bare return err — same, larger sweep 28 files, ~50 wraps
This PR Existing fmt.Errorf calls that already had context but used %v/%s instead of %w 51 files, 199 verb changes

The prior PRs added wrapping where none existed (bare return err). This PR fixes wrapping that was already there but used the wrong format verb, silently converting errors to strings and breaking errors.Is()/errors.As() chains.

Details

Using %v or %s in fmt.Errorf converts the error to a plain string, silently breaking the error chain. This prevents errors.Is() and errors.As() from matching wrapped errors, making error handling unreliable.

Lines where the format verb corresponds to a non-error argument (strings, slices, status codes) or where err may be nil due to compound conditions (err != nil || stderr != "") are intentionally left as %v.

Related to

Test plan

  • make build passes
  • make test passes (all packages)
  • golangci-lint run ./... reports 0 issues
  • Verified all 55 remaining %v/%s calls are legitimate non-error uses

@dcibot

dcibot commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Replace %v and %s with %w in fmt.Errorf calls where the argument is an
error value. Using %v or %s converts the error to a plain string,
breaking the error chain and preventing callers from using errors.Is()
or errors.As() to inspect wrapped errors.

This change covers 199 call sites across 50 files. Lines where the
format verb corresponds to a non-error argument (strings, slices,
status codes) or where err may be nil due to compound conditions
(err != nil || stderr != "") are intentionally left as %v.

Test assertions using assert.Equal(t, errors.New(...), err) were
updated to assert.EqualError(t, err, msg) since %w produces
*fmt.wrapError instead of *errors.errorString.
@sebrandon1
sebrandon1 force-pushed the fix/error-wrapping-preserve-chains branch from c6b0938 to 45a25b0 Compare June 17, 2026 17:59
@dcibot

dcibot commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

@sebrandon1
sebrandon1 merged commit 54b878b into redhat-best-practices-for-k8s:main Jun 17, 2026
43 checks passed
@dcibot

dcibot commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants