Problem
lenstringzero's diagnostic message hardcodes the literal placeholder text s and len(s) instead of interpolating the actual matched expression, for every violation it reports (not just the alias-tracking path).
Location
pkg/linters/lenstringzero/lenstringzero.go:74-79
pass.Report(analysis.Diagnostic{
Pos: expr.Pos(),
End: expr.End(),
Message: fmt.Sprintf(`use s %s "" to check for %s string instead of len(s) %s %d`, fixOp, cmpVerb, normalOp, lit),
SuggestedFixes: fixes,
})
Only fixOp, cmpVerb, normalOp, and lit are interpolated — s and len(s) are literal text in the format string, not placeholders for the real expression.
Evidence / impact
For source code like:
the emitted diagnostic reads:
use s == "" to check for empty string instead of len(s) == 0
instead of the actionable:
use username == "" to check for empty string instead of len(username) == 0
This makes every diagnostic from this linter misleading about which variable is affected — a contributor has to cross-reference the reported line/column manually instead of reading the message. It's the same defect class already fixed twice elsewhere in this codebase for the identical reason (#53579 bytescomparestring, #52826 stringbytesroundtrip: "diagnostic message hardcodes ... and misrepresents"), but it has reappeared in lenstringzero, which is not yet CI-enforced (missing from LINTER_FLAGS in .github/workflows/cgo.yml), so it hasn't been caught by day-to-day usage yet.
The alias-tracking path (n := len(s); if n == 0) is doubly affected: it reports len(s) even though the source text is n, and there is no s in scope at all — so the message references code that isn't there.
Recommendation
Use astutil.NodeText(pass.Fset, lenArg) (already imported and used by buildLenStringFix) to build the message dynamically for both the direct and alias cases, mirroring how sibling linters like mapdeletecheck (mText/kText) and the current stringbytesroundtrip/bytescomparestring already do it correctly.
Validation checklist
Effort
Small — the fix is confined to one fmt.Sprintf call plus updating expected test fixture strings.
Generated by 🤖 Sergo - Serena Go Expert · agent · 275.9 AIC · ⌖ 9.07 AIC · ⊞ 6.8K · ◷
Problem
lenstringzero's diagnostic message hardcodes the literal placeholder textsandlen(s)instead of interpolating the actual matched expression, for every violation it reports (not just the alias-tracking path).Location
pkg/linters/lenstringzero/lenstringzero.go:74-79Only
fixOp,cmpVerb,normalOp, andlitare interpolated —sandlen(s)are literal text in the format string, not placeholders for the real expression.Evidence / impact
For source code like:
the emitted diagnostic reads:
instead of the actionable:
This makes every diagnostic from this linter misleading about which variable is affected — a contributor has to cross-reference the reported line/column manually instead of reading the message. It's the same defect class already fixed twice elsewhere in this codebase for the identical reason (#53579
bytescomparestring, #52826stringbytesroundtrip: "diagnostic message hardcodes ... and misrepresents"), but it has reappeared inlenstringzero, which is not yet CI-enforced (missing fromLINTER_FLAGSin.github/workflows/cgo.yml), so it hasn't been caught by day-to-day usage yet.The alias-tracking path (
n := len(s); if n == 0) is doubly affected: it reportslen(s)even though the source text isn, and there is nosin scope at all — so the message references code that isn't there.Recommendation
Use
astutil.NodeText(pass.Fset, lenArg)(already imported and used bybuildLenStringFix) to build the message dynamically for both the direct and alias cases, mirroring how sibling linters likemapdeletecheck(mText/kText) and the currentstringbytesroundtrip/bytescomparestringalready do it correctly.Validation checklist
username, or the alias variable name for then := len(s)case), not literals/len(s)analysistestgolden files updated/added to assert the exact message text for a non-trivial variable nameSuggestedFixesbehavior (autofix is already correct; only the message is wrong)Effort
Small — the fix is confined to one
fmt.Sprintfcall plus updating expected test fixture strings.