Skip to content

lint: a nolint directive naming a disabled linter is reported by nothing #306

Description

@OmarAlJarrah

Problem

nolintlint (allow-unused: false) fails the gate on a //nolint directive that suppresses
nothing — but only when the linter it names is enabled. A directive naming a linter that is
disabled, or that does not exist at all, is silently ignored by golangci-lint's nolint processor
and reported by nothing in the gate.

Verified by execution on golangci-lint 2.12.2 / go1.26.4, planting each form on one line of
pass/validate_propids_test.go and running golangci-lint run with a cleaned cache:

planted directive reported?
//nolint:unparam // … (enabled, nothing to suppress) yes — is unused for linter "unparam" (nolintlint)
//nolint:forcetypeassert // … (real linter, not enabled) no — 0 issues.
//nolint:notarealinter // … (no such linter) no — 0 issues.

This is not hypothetical: the //nolint:forcetypeassert directive that stood at
pass/validate_propids_test.go:86 was of exactly the second kind. forcetypeassert has never been
in the enabled set, so the directive never suppressed anything from the day it was written, and no
gate step could have said so.

The failure mode is the one a suppression comment is worst at: it reads as a live constraint on the
code under it, and re-checking it by hand is the only thing that can tell you otherwise.

Proposed direction

Cross-check the linter names appearing in //nolint directives against the enabled set, and fail
when a directive names one that is not enabled. The enabled set is derivable
(golangci-lint linters --json, or parsing .golangci.yml against
golangci-lint help linters), and the directives are a git ls-files '*.go' grep away, so this
fits the existing bundled gate job as one more step rather than a new workflow.

Acceptance

  • A directive naming a disabled or unknown linter fails the gate.
  • The check is proven to bite by planting one of each form and watching it go red.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions