Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix cacheRecoveryError's %v-not-%w bug and extend errorfwrapv/fmterrorfnoverbs to concatenated format strings #58715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Uh oh!
There was an error while loading. Please reload this page.
Fix cacheRecoveryError's %v-not-%w bug and extend errorfwrapv/fmterrorfnoverbs to concatenated format strings #58715
Changes from all commits
a5902858ff6b3da86269c94b2883File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This linter still misclassifies error arguments after an opaque prefix because
ResolveFormatStringpreserves later verbs but throws away how many runtime verbs the prefix may have consumed.fmt.Errorf(prefix+" suffix: %v", err)is valid whenprefixalready contains%w, yet this code will still flag the trailing%vpath incorrectly.💡 The analyzer can only reason about argument positions when every earlier verb is known.
Once a non-literal segment appears before a literal verb,
nextArgIdxis no longer trustworthy: the runtime prefix may consume zero, one, or several arguments, including an existing%w. That meansclassifyErrorArgscan attach the later%vto the wrong argument and emit a bogus diagnostic. A safer fix is to stop analyzing any call whose unresolved segment appears before the verb you want to judge, or carry structured segments plus an "unknown arg consumption" state instead of flattening to a plain string.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change makes
fmterrorfnoverbsreporterrors.Newfor concatenated format strings even when the dynamic prefix may contain real verbs, so it will now suggest a broken rewrite for validfmt.Errorf(prefix+" suffix")calls.💡 A non-literal prefix means "no verbs in the literal tail" is not the same as "no verbs at runtime."
ResolveFormatStringonly proves facts about the literal pieces. Ifprefixcontains%d, the existing call still has formatting semantics anderrors.Newis not equivalent. The current generic message avoids a bad auto-fix string, but the diagnostic itself is still unsound. Limit this rule to fully literal format strings, or teach the helper to surface an "unknown verbs present" state that suppresses the report.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/diagnosing-bugs] This branch's report message differs (
errors.New(%q)for plain literals vs. a bare genericerrors.Newfor concatenated ones) but neither test asserts the exact suggested message text for the concatenated case —concatNoVerbs'swantregex only anchors on the prefix, so a future edit to the fallback wording wouldn't be caught by CI.💡 Suggestion
Consider tightening the
wantregex inconcatNoVerbs(fmterrorfnoverbs testdata) to match the full generic message, so the two code paths (plain-literal vs concatenated) stay independently verified as the message wording evolves.@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkg/linters/internal/astutil/astutil.go:L709: yagni: recursive ResolveFormatString helper with opaque-placeholder logic and supporting docs. Inline a tiny local helper in each linter and keep the AST handling scoped to the specific cases they need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd] Good coverage of the opaque-placeholder verb-fabrication boundary, but there's no regression test for the argument-index shift when an opaque operand's runtime value itself contains a
%-verb (e.g.prefix := "%d: ").ResolveFormatStringcorrectly can't resolve that content, but downstream consumers (parseFormatVerbsin errorfwrapv) still count implicit arg indices as if the opaque segment consumed zero verbs, which can silently misattribute later verbs to the wrongcall.Argsindex.💡 Suggested regression test
A case like the reviewer's own example is worth adding as an explicit testdata scenario in
errorfwrapv/testdata(or a targetedparseFormatVerbs/classifyErrorArgsunit test) that documents the current known-limitation, so a future contributor doesn't need to rediscover it from the existing PR review comment thread.@copilot please address this.