blankassigncomma (71st linter): flags 14+ production sites that are deliberate idiomatic error-discards
- Dominant language
- Go
- Stars
- 5.1k
- Forks
- 541
- Avg merge
- 5h 48m
- Merged PRs (30d)
- 773
Description
Summary
blankassigncomma (added 2026-09-14, PR 60893, 71st registered analyzer) flags any assignment statement whose left-hand side is 2 or more consecutive blank identifiers (`_, _ = f()`), on the theory that discarding every result is a code smell. A first-time full audit against the actual codebase shows this design flags essentially every real usage of a well-established, already-idiomatic Go pattern in this repo: explicitly discarding a return value (almost always a guaranteed-nil or genuinely non-critical error) to satisfy other tooling and readability conventions, not a mistake.
Evidence: 14 production sites (excluding testdata and _test.go) match the rule today
- pkg/console/spinner.go:208 `_, _ = s.program.Run()`
- pkg/workflow/maintenance_cron.go:46 `_, _ = io.WriteString(h, repoSlug)`
- pkg/workflow/compiler_yaml_main_job.go:37 `_, _ = c.computeAllowedDomainsForSanitization(data)` (this is the PRs own cited motivating example)
- pkg/workflow/strings.go:174-175 `_, _ = io.WriteString(h, strings.ToUpper(name))` and `_, _ = io.WriteString(h, content)`
- pkg/cli/outcome_eval_review.go:311 `_, _ = fmt.Sscanf(value, "%d", &parsed)`
- pkg/cli/graders_run.go:365 `_, _ = buffer.Buffer.Write(data[:remaining])`
- pkg/cli/update_extension_check.go:161 `_, _ = io.Copy(os.Stderr, &firstAttemptBuf)`
- pkg/cli/deps_outdated.go:181 and pkg/cli/deps_security.go:164 `_, _ = io.Copy(io.Discard, resp.Body)`
- pkg/cli/trial_repository.go:183 `_, _ = fmt.Scanln(&userInput)` (with an explicit "Ignore error" comment)
- pkg/cli/codemod_steps_run_secrets_env.go:450 and pkg/cli/bootstrap_profile_github_app.go:284 `_, _ = io.WriteString(h, body)` / `_, _ = io.WriteString(w, registrationPage)`
- pkg/cli/docker_images.go:354 `_, _ = StartDockerImageDownload(ctx, img.image)`
The strongest single data point is pkg/workflow/strings.go:173, one line above the flagged statement: `// hash.Hash.Write never returns an error in practice, but check to satisfy gosec G104`. That comment documents exactly why the double-blank-assign exists: hash.Hash.Write is contractually guaranteed by the io.Writer/hash docs to never return a non-nil error, and the explicit `_, _ =` is there only to satisfy a DIFFERENT static analysis tool (gosec G104, unchecked-error). blankassigncomma re-flags the very pattern that was written to appease static analysis in the first place.
This connects to .golangci.yml line 37, which disables errcheck repo-wide with the comment "Disabled due to exclude-functions not working properly in golangci-lint v2" - meaning this codebase already relies on explicit `_, _ =` as the manual substitute for an exclude-list mechanism that does not work here. blankassigncomma has no allow-list/exclude-list of its own, so it directly reintroduces the same friction errcheck exclude-functions was meant to solve.
Impact
If blankassigncomma is ever added to cgo.yml LINTER_FLAGS (it is currently unenforced, diagnostic-only), it will immediately require nolint annotations or code churn at all 14+ sites above, none of which are bugs. Left as-is, it also means any future contributor writing this same widely-used idiom anywhere in the codebase gets a lint warning encouraging them to either remove the assignment (fine when errcheck-equivalent enforcement does not apply) or "check the results instead" (nonsensical for a guaranteed-nil hash.Write error).
Recommendation
Before considering CI enforcement, give blankassigncomma an allow-list or heuristic exclusion comparable to what a working errcheck exclude-functions list would provide, for example: skip calls whose first return type is bound to a receiver method literally named Write when the receiver type embeds/implements hash.Hash, or more simply, recognize a same-line or immediately-preceding explanatory comment (similar to how internal/nolint already suppresses per-line) as an intentional-discard marker rather than only supporting a full linter-name nolint directive. At minimum, document in the linters own doc comment that call sites already covered by a documented never-errors contract (hash.Hash.Write, and similar) are expected false positives, and audit these 14 sites explicitly before flipping the linter on.
Validation checklist
- Decide on an exclusion mechanism (type-based allow-list vs comment heuristic) before adding to LINTER_FLAGS
- Add a testdata case for `_, _ = h.Write(...)` on a hash.Hash receiver to document the intended behavior either way
- Re-run against pkg/ after the mechanism lands and confirm the 14 sites above no longer trigger (or are explicitly nolint-annotated as a one-time cleanup)
Effort: small design change (allow-list or comment heuristic) plus updated testdata; no urgency since the linter is not yet CI-enforced.
> [!WARNING]
>
> Firewall blocked 1 domain
>
> The following domain was blocked by the firewall during workflow execution:
>
> - `api.anthropic.com`
>
> To allow these domains, add them to the `network.allowed` list in your workflow frontmatter:
>
> ```yaml
> network:
> allowed:
> - defaults
> - "api.anthropic.com"
> ```
>
> See [Network Configuration](https://github.github.com/gh-aw/reference/network/) for more information.
>
>
> Generated by [🤖 Sergo - Serena Go Expert](https://github.com/github/gh-aw/actions/runs/34926336224) · claude · agent · 189.6 AIC · ⌖ 9.58 AIC · ⊞ 6.8K · [◷](https://github.com/search?q=repo%3Agithub%2Fgh-aw+is%3Aissue+%22gh-aw-workflow-call-id%3A+github%2Fgh-aw%2Fsergo%22&type=issues)
> - [x] expires on Sep 21, 2026, 7:57 PM UTC-08:00
Contributor guide
Research direction
Start with the blankassigncomma implementation and its testdata, then inspect .golangci.yml line 37 and cgo.yml LINTER_FLAGS. Decide on the proposed allow-list or comment heuristic, add the `_, _ = h.Write(...)` testdata case, and rerun the linter against pkg/ to verify the 14 listed sites are handled or explicitly annotated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- testing-qa, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100