[linter-miner] Add blank-assign-comma linter - #60893
Conversation
Implements a new linter that flags assignments with multiple consecutive blank identifiers (e.g., `_, _ = f()`), which is often a code smell indicating the result should be checked or the function should be called without assignment. This pattern was identified in the codebase at pkg/workflow/compiler_yaml_main_job.go where `_, _ = c.computeAllowedDomainsForSanitization(data)` appears. The linter helps catch cases where developers may have unintentionally ignored multiple return values. The linter: - Flags assignments with 2+ consecutive leading blank identifiers - Excludes generated files and files with nolint directives - Provides a clear message suggesting the result should be checked - Includes comprehensive test cases Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
✅ Test Quality Sentinel completed test quality analysis. Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff
|
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅
|
|
Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "github.com"See Network Configuration for more information.
|
|
Warning Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding. What happenedThe threat detection engine failed to produce results. Review the workflow run logs for details.
|
|
✅ Ponytail Reviewer completed successfully! Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "ab.chatgpt.com"See Network Configuration for more information.
|
🏗️ ADR Required - draft added for PR #60893I required ADR enforcement for this PR because it adds more than 100 new lines in business-logic directories ( Evidence used
Action takenI added a draft ADR at
Next action for the authorPlease review and refine the draft ADR, then keep it with this PR as the design record for introducing this linter. Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "github.com"See Network Configuration for more information.
|
There was a problem hiding this comment.
Lean already. Ship.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
ab.chatgpt.com
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "ab.chatgpt.com"See Network Configuration for more information.
Generated by ✂️ Ponytail Reviewer for #60893 · codex · gpt53codex · 4.18 AIC · ⌖ 4.01 AIC · ⊞ 12.4K
Comment /ponytail to run again
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /tdd — requesting changes: the linter's core detection only catches leading consecutive blank identifiers, missing the same code smell when it appears mid-assignment or trailing (e.g. a, _, _ := f3()). I verified this locally by building cmd/linters and running it against test cases — trailing/middle blank patterns produce zero diagnostics while the leading-blank case is correctly flagged.
📋 Key Themes & Highlights
Key Themes
- Detection gap:
checkBlankAssignCommabreaks out of its loop on the first non-blank identifier, so it only counts a leading run of blanks. Real-world patterns likea, _, _ := f3()(motivated by the PR's own stated goal of catching "unintentional result ignoring") slip through undetected. - Test coverage: the testdata file only exercises leading-blank cases, so this gap wasn't caught by the test suite. Per
/tdd, edge cases for mid/trailing blanks should be added (and would currently fail, proving the gap). - Minor: testdata fixture has trailing whitespace and fails
gofmt -l.
Positive Highlights
- ✅ Clean, minimal analyzer that follows the existing linter package conventions (
analyzerutil,filecheck,nolintintegration). - ✅ Correctly registered in
pkg/linters/registry.goin alphabetical order. - ✅ Test uses
analysistestidiomatically, consistent with sibling linters.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 48.6 AIC · ⌖ 15.1 AIC · ⊞ 10.4K
Comment /matt to run again
| } | ||
|
|
||
| // Count consecutive blanks from the left | ||
| consecutiveBlanks := 0 |
There was a problem hiding this comment.
[/tdd] Only leading consecutive blanks are counted, so a, _, _ := f3() (trailing) and a, _, _, b := f4() (middle) are silently missed — yet these are the same code smell the PR targets. Verified locally: only leading-blank patterns trigger a diagnostic; mid/trailing multi-blank assignments produce zero warnings.
💡 Suggested fix
Count blank identifiers anywhere in assign.Lhs, not just a leading run:
blanks := 0
for _, lhs := range assign.Lhs {
if ident, ok := lhs.(*ast.Ident); ok && ident.Name == "_" {
blanks++
}
}
if blanks < 2 {
return
}Add testdata cases for a, _, _ := f3() and a, _, _, b := f4() to lock in the fix (per /tdd red-green-refactor, these should be written first as failing cases).
@copilot please address this.
| func good() { | ||
| // Single blank is OK (common pattern for ignoring single return value) | ||
| _ = someFunction() | ||
|
|
There was a problem hiding this comment.
[/tdd] This testdata file has trailing whitespace on blank lines (e.g. after line 6, 10) and fails gofmt -l. Testdata is normally excluded from CI formatting checks, but keeping fixtures gofmt-clean avoids surprises if that changes and is a quick fix.
💡 Fix
gofmt -w pkg/linters/blankassigncomma/testdata/src/blankassigncomma/blankassigncomma.go@copilot please address this.
There was a problem hiding this comment.
🟡 Changes recommended
The analyzer produces false positives and its registration leaves required documentation and CI synchronization tests failing.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds a custom Go analyzer to detect assignments that discard multiple results.
Changes:
- Implements and registers
blankassigncomma. - Adds analysistest coverage and fixtures.
File summaries
| File | Description |
|---|---|
pkg/linters/registry.go |
Registers the analyzer. |
pkg/linters/blankassigncomma/blankassigncomma.go |
Implements detection and exclusions. |
pkg/linters/blankassigncomma/blankassigncomma_test.go |
Runs analyzer tests. |
pkg/linters/blankassigncomma/testdata/src/blankassigncomma/blankassigncomma.go |
Provides test cases. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 2
- Review effort level: Balanced (auto)
Note
Copilot is running an experiment and ran this review at Balanced.
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| var allAnalyzers = []*analysis.Analyzer{ | ||
| appendbytestring.Analyzer, | ||
| appendoneelement.Analyzer, | ||
| blankassigncomma.Analyzer, |
| } | ||
|
|
||
| // Flag if we have 2 or more consecutive blanks | ||
| if consecutiveBlanks < 2 { |
There was a problem hiding this comment.
The blankassigncomma linter's detection logic is too broad: it flags any assignment with 2+ leading blank identifiers, not just assignments where all identifiers are blank. This means idiomatic Go like _, _, err := f() gets flagged, even though err is used.
I verified this by building the linter (go build ./cmd/linters) and running it against this repo (./linters -blankassigncomma ./...): it produces 25 findings, and nearly all are legitimate patterns with a used trailing variable, not the "ignoring all results" code smell the PR intends to catch. Left an inline comment with the specific fix (require consecutiveBlanks == len(assign.Lhs)) and example locations.
🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 60.2 AIC · ⌖ 13.7 AIC · ⊞ 8.4K
| } else { | ||
| break | ||
| } | ||
| } |
There was a problem hiding this comment.
This linter is overly aggressive and would produce many false positives across the existing codebase.
Because the linter only checks whether the first N identifiers on the LHS are blank (not whether all are blank), it flags perfectly idiomatic code such as:
_, _, err := parseRepositoryName(repo) // pkg/workflow/repository_features_validation.go:424
if _, _, deltaValid := parseOptionalNonNegativeFloat(...); deltaValid { // pkg/cli/token_usage_aic.go:47Running the built linter against this repo's own ./... surfaces 25 findings, nearly all of which are legitimate patterns where a trailing variable (err, deltaValid, etc.) is used — only the earlier return values are discarded. That's a completely normal and common Go idiom, not a code smell.
Suggested fix: only flag when all LHS identifiers are blank (i.e. consecutiveBlanks == len(assign.Lhs)), rather than just a leading run of 2+ blanks. That matches the PR description's stated intent ("Multiple consecutive blank assignments... The developer knows the function returns values but chose to ignore all of them") and the example given (_, _ = c.computeAllowedDomainsForSanitization(data)), while avoiding false positives on _, _, err := f()-style code.
Also, the testdata in this PR doesn't cover this case (mixed blank + real trailing identifier with 2+ leading blanks), which is why the false positives weren't caught by go test.
@copilot please address this.
|
@copilot This PR has multiple review findings to address before maintainers investigate further.
Relevant review activity:
Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "github.com"See Network Configuration for more information.
|
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Fixed in 255f38b:
|
Summary
This PR implements a new Go static analysis linter called blank-assign-comma that flags assignment statements with multiple consecutive blank identifiers.
What It Catches
The linter detects patterns like:
Why This Matters
Multiple consecutive blank assignments (
_, _, ...) are often a code smell indicating:someFunction()a, _ := f()(intentional, less suspicious)Evidence from Codebase
This pattern appears in production code:
pkg/workflow/compiler_yaml_main_job.go:_, _ = c.computeAllowedDomainsForSanitization(data)The linter helps catch similar patterns automatically.
Implementation Details
pkg/linters/blankassigncomma/// nolintdirectivestestdata/src/blankassigncomma/pkg/linters/registry.goTesting
go test ./pkg/linters/blankassigncomma/... go build ./cmd/linters ./linters -blankassigncomma ./pkg/linters/blankassigncomma/testdata/src/blankassigncomma/All tests pass and the linter correctly identifies violations in test data while ignoring intentional single-blank assignments.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
api.github.com[!TIP]
api.github.comis blocked because GitHub API access uses the built-in GitHub tools by default. Instead of addingapi.github.comtonetwork.allowed, usetools.github.mode: gh-proxyfor direct pre-authenticated GitHub CLI access without requiring network access toapi.github.com:See GitHub Tools for more information on
gh-proxymode.To allow these domains, add them to the
network.allowedlist in your workflow frontmatter:See Network Configuration for more information.