Skip to content

4 library-scope linters still miss the pass.Pkg.Name()==main guard (issue 63342 auto-expired, 4th reverse-phantom) #65226

Description

@github-actions

Lineage: #59627 (filed R61) -> #61518 (R69 refile) -> #63342 (R77 refile, auto-expired closed/not_planned on 2026-10-02) -> this issue (R85 refile). Fourth time this exact bug has been filed; the code has never changed across any of the three prior closures.

Bug

Four library-scope linters classify a package as library code (vs. an executable main package) using only a path-substring heuristic, with zero check of the actual package declaration:

  • pkg/linters/osexitinlibrary/osexitinlibrary.go:23
  • pkg/linters/rawloginlib/rawloginlib.go:30
  • pkg/linters/logfatallibrary/logfatallibrary.go:35
  • pkg/linters/panic-in-library-code/panic-in-library-code.go:36

All four use the identical guard:

if strings.HasSuffix(pkgPath, "/main") || strings.Contains(pkgPath, "/cmd/") {

Compare the sibling linter pkg/linters/osgetenvlibrary/osgetenvlibrary.go:22, which does this correctly:

if pass.Pkg.Name() == "main" || strings.HasSuffix(pkgPath, "/main") || strings.Contains(pkgPath, "/cmd/") {

Impact

Any package whose import path does not end in /main or contain /cmd/, but whose package clause is package main, is misclassified as library code by all four linters. Two live examples of package main outside a /main or /cmd/ path: internal/tools/actions-build/main.go (3 os.Exit(1) sites) and internal/tools/generate-action-metadata/main.go (2 os.Exit(1) sites).

Status: latent today. Makefile:868 sets the default LINTER_PACKAGES ?= ./cmd/... ./pkg/..., which excludes ./internal/..., so these specific sites are not scanned by default. This is a structural correctness gap rather than a deliberate scope limit, and would misfire the moment LINTER_PACKAGES is widened or a new package-main-without-main-ish-dirname is added under ./pkg/... or ./cmd/....

Re-verified 2026-10-03: all four files re-read in full; zero occurrences of pass.Pkg.Name() outside osgetenvlibrary.go and ossetenvlibrary.go.

Recommendation

Add pass.Pkg.Name() == "main" || to the front of the OR-chain in all four files, matching the osgetenvlibrary/ossetenvlibrary reference implementation exactly.

Validation checklist

  • Add a testdata package declared package main under a directory name that does not end in /main or contain /cmd/
  • Confirm all four linters now correctly skip it (no false positive)
  • Confirm existing /main and /cmd/ path-based testdata cases are unaffected

Effort: small -- one-line guard addition x4 files.

Generated by 🤖 Sergo - Serena Go Expert · claude · agent · 317.8 AIC · ⌖ 7.26 AIC · ⊞ 5.3K · ◷

  • expires on Oct 9, 2026, 8:11 PM UTC-08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cookieIssue Monster Loves Cookies!sergo

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions