You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The entire analysis is gated by a single nodeFilter entry:
nodeFilter:= []ast.Node{(*ast.AssignStmt)(nil)}
(fprintferrorunchecked.go:40). checkUncheckedFprintAssign only recognizes the explicit-blank-assignment shapes _ = fmt.Fprintf(...) and _, _ = fmt.Fprintf(...). A bare statement call with no assignment at all, e.g. fmt.Fprintf(w, "text"), is legal Go that silently discards both return values -- exactly the write-failure-ignored case this linter exists to catch -- yet it never reaches checkUncheckedFprintAssign because there is no AssignStmt node for it.
Evidence
Grep across pkg/ (excluding _test.go) for the bare-statement shape ^\tfmt\.(Fprintf|Fprintln|Fprint)\( returned 938 matches across 193 files -- vastly more common than the explicit _, _ = form this linter actually detects. Two concrete production sites:
pkg/console/confirm.go:53-56 -- fmt.Fprintf(out, ...) writing to an io.Writer parameter (e.g. os.Stdout in real callers), with zero error handling. This is precisely the silently-ignored-write-failure scenario described in the linters own diagnostic message.
pkg/workflow/workflow_errors.go:99 -- fmt.Fprintf(&b, ...) building an error string via bytes.Buffer.
CI enforcement
.github/workflows/cgo.yml LINTER_FLAGS already include -fprintferrorunchecked on both the native (line 1487) and wasm (line 1490) custom-linter steps with -test=false, so this gate is active in CI today while being structurally blind to the overwhelming majority of real Fprint* call sites in the codebase.
Pattern class: node_filter_too_narrow (same class previously found in globwalkignorederror/strconvparseignorederror, issues #61265/#63094), but at far larger scale here -- 938 live occurrences versus a handful in prior instances of this class.
Recommendation
Add an *ast.ExprStmt case alongside the existing *ast.AssignStmt case in run() (fprintferrorunchecked.go:40-50): unwrap the ExprStmt to its *ast.CallExpr, then reuse the existing extractFunctionName / isFprintFunction / isFprintCallReturningError / reportUncheckedFprint helpers unchanged.
Validation checklist
Add a testdata case for the bare-statement form, e.g. fmt.Fprintf(w, "text") as a standalone ExprStmt, expecting a diagnostic
Confirm existing AssignStmt-based good/bad cases still pass unchanged
Run make golint-custom LINTER_FLAGS="-fprintferrorunchecked -test=false" against pkg/console and pkg/workflow to confirm the fix surfaces new findings without introducing false positives on checked calls
Effort: small -- one new ExprStmt branch reusing all existing helper functions.
Activity