PluginBench
Skill
Pass
Audit score 90

golang-lint

samber/cc-skills-golang

Configure golangci-lint, interpret lint output, and suppress warnings in Go projects.

What is golang-lint?

golang-lint guides configuration of golangci-lint (Go's standard linting aggregator), interpretation of lint findings, and use of nolint directives. Use when setting up code quality tooling, fixing lint warnings, or choosing which linters to enable.

  • Run golangci-lint with 100+ aggregated linters in parallel across Go codebases
  • Configure .golangci.yml with production-ready linter selection and per-linter settings
  • Auto-fix issues where possible using golangci-lint run --fix
  • Suppress false positives with specific //nolint:linter-name // reason directives
  • Interpret lint output and map findings to their source linters for targeted fixes

How to install golang-lint

npx skills add https://github.com/samber/cc-skills-golang --skill golang-lint
Prerequisites
  • golangci-lint installed: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
  • Go toolchain (go command) available
  • A .golangci.yml file in the project root (can be generated from recommended template)
Claude Code
Cursor
Windsurf
Cline

How to use golang-lint

  1. 1.Install golangci-lint if not already present
  2. 2.Copy or generate a .golangci.yml configuration (use the recommended production-ready setup as a starting point)
  3. 3.Run golangci-lint run ./... to lint all Go files and review output
  4. 4.Use golangci-lint run --fix ./... to auto-fix issues where possible
  5. 5.For legacy codebases, set issues.new-from-rev in .golangci.yml to lint only new/changed code
  6. 6.Suppress remaining false positives with //nolint:linter-name // justification directives
  7. 7.Run golangci-lint fmt ./... before committing to format code
  8. 8.Add lint and lint-fix targets to your Makefile for team consistency

Use cases

Good for
  • Setting up linting on a new Go project with a recommended .golangci.yml configuration
  • Fixing lint warnings on existing code and choosing which issues to suppress vs. resolve
  • Adopting linting on a legacy codebase using incremental adoption (new-from-rev) and parallel cleanup agents
  • Configuring linter-specific rules (timeouts, exclusions, concurrency) for large or slow repositories
  • Migrating from golangci-lint v1 to v2 configuration format
Who it's for
  • Go developers setting up or maintaining code quality tooling
  • Teams adopting linting on legacy codebases
  • Code reviewers interpreting lint output and nolint justifications
  • DevOps engineers configuring linting in CI pipelines (with golang-continuous-integration skill)

golang-lint FAQ

When should I use //nolint vs. fixing the underlying issue?

Always fix the root cause first. Use //nolint only for genuine false positives or fire-and-forget patterns (e.g., logging errors that are not actionable). Every //nolint directive must specify the linter name and include a justification comment; the nolintlint linter enforces this.

How do I handle 'deadline exceeded' errors?

Increase or remove the run.timeout setting in .golangci.yml. golangci-lint v2 defaults to no timeout (0), so this is rare. If it persists, reduce run.concurrency or exclude slow paths.

Can I lint only new code instead of the entire codebase?

Yes. Set issues.new-from-rev: HEAD~1 (or another ref) in .golangci.yml to lint only code changed since that revision. This enables incremental adoption on legacy codebases.

How do I know which linter flagged an issue?

The linter name appears in parentheses at the end of each lint message (e.g., 'file.go:42:10: message (linter-name)'). Use golangci-lint linters to list all available linters and the linter-reference.md for descriptions.

Should I ever suppress security linters like gosec or bodyclose?

Rarely. Security linters flag real risks. Only suppress with a very strong justification and explicit approval. Use //nolint:gosec // reason and document why the risk is acceptable.

Full instructions (SKILL.md)

Source of truth, from samber/cc-skills-golang.


name: golang-lint description: "Linting best practices and golangci-lint configuration for Golang projects — running linters, configuring .golangci.yml, suppressing warnings with nolint directives, interpreting lint output, and selecting linters. Use when configuring golangci-lint, asking about lint warnings or nolint suppressions, setting up code quality tooling, or choosing linters. Also use when the user mentions golangci-lint, go vet, staticcheck, or revive. Not for wiring a lint step into a GitHub Actions pipeline (→ See samber/cc-skills-golang@golang-continuous-integration skill)." user-invocable: true license: MIT compatibility: Designed for Claude Code, Codex or similar harness, and for projects using Golang. metadata: author: samber version: "1.4.1" openclaw: emoji: "🧹" homepage: https://github.com/samber/cc-skills-golang requires: bins: - go - golangci-lint install: - kind: brew formula: golangci-lint bins: [golangci-lint] allowed-tools: Read Edit Write Glob Grep Bash(go:) Bash(golangci-lint:) Bash(git:*) Agent paths:

  • "**/*.go"
  • ".golangci.yml"

Persona: You are a Go code quality engineer. You treat linting as a first-class part of the development workflow — not a post-hoc cleanup step.

Orchestration mode: Fan out the five sub-agents described in the "Parallelizing Legacy Codebase Cleanup" section (auto-fix, security linters, error handling, style/formatting, code quality) when adopting linting on a legacy codebase, so independent linter categories are fixed concurrently. On Claude Code, use ultracode to opt into multi-agent orchestration explicitly.

Modes:

  • Setup mode — configuring .golangci.yml, choosing linters, enabling CI: follow the configuration and workflow sections sequentially.
  • Coding mode — writing new Go code: launch a background agent running golangci-lint run --fix on the modified files only while the main agent continues implementing the feature; surface results when it completes.
  • Interpret/fix mode — reading lint output, suppressing warnings, fixing issues on existing code: start from "Interpreting Output" and "Suppressing Lint Warnings"; use parallel sub-agents for large-scale legacy cleanup.

Dependencies:

  • golangci-lint: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

Go Linting

Overview

golangci-lint is the standard Go linting tool. It aggregates 100+ linters into a single binary, runs them in parallel, and provides a unified configuration format. Run it frequently during development and always in CI.

Every Go project MUST have a .golangci.yml — it is the source of truth for which linters are enabled and how they are configured. See the recommended configuration for a production-ready setup with 48 linters enabled.

Quick Reference

# Run all configured linters
golangci-lint run ./...

# Auto-fix issues where possible
golangci-lint run --fix ./...

# Format code (golangci-lint v2+)
golangci-lint fmt ./...

# Run a single linter only
golangci-lint run --enable-only govet ./...

# List all available linters
golangci-lint linters

# Verbose output with timing info
golangci-lint run --verbose ./...

Configuration

The recommended .golangci.yml provides a production-ready setup with 33 linters. For configuration details, linter categories, and per-linter descriptions, see the linter reference — which linters check for what (correctness, style, complexity, performance, security), descriptions of all 33+ linters, and when each one is useful.

Suppressing Lint Warnings

Use //nolint directives sparingly — fix the root cause first.

// Good: specific linter + justification
//nolint:errcheck // fire-and-forget logging, error is not actionable
_ = logger.Sync()

// Bad: blanket suppression without reason
//nolint
_ = logger.Sync()

Rules:

  1. //nolint directives MUST specify the linter name: //nolint:errcheck not //nolint
  2. //nolint directives MUST include a justification comment: //nolint:errcheck // reason
  3. The nolintlint linter enforces both rules above — it flags bare //nolint and missing reasons
  4. NEVER suppress security linters (gosec, bodyclose, sqlclosecheck) without a very strong reason

For comprehensive patterns and examples, see nolint directives — when to suppress, how to write justifications, patterns for per-line vs per-function suppression, and anti-patterns.

Development Workflow

  1. Linters SHOULD be run after every significant change: golangci-lint run ./...
  2. Auto-fix what you can: golangci-lint run --fix ./...
  3. Format before committing: golangci-lint fmt ./...
  4. Incremental adoption on legacy code: set issues.new-from-rev in .golangci.yml to only lint new/changed code, then gradually clean up old code

Makefile targets (recommended):

lint:
	golangci-lint run ./...

lint-fix:
	golangci-lint run --fix ./...

fmt:
	golangci-lint fmt ./...

For CI pipeline setup (GitHub Actions with golangci-lint-action), see the samber/cc-skills-golang@golang-continuous-integration skill.

Interpreting Output

Each issue follows this format:

path/to/file.go:42:10: message describing the issue (linter-name)

The linter name in parentheses tells you which linter flagged it. Use this to:

  • Look up the linter in the reference to understand what it checks
  • Suppress with //nolint:linter-name // reason if it's a false positive
  • Use golangci-lint run --verbose for additional context and timing

Common Issues

ProblemSolution
"deadline exceeded"Set or increase run.timeout in .golangci.yml; golangci-lint v2 defaults to no timeout (0)
Too many issues on legacy codeSet issues.new-from-rev: HEAD~1 to lint only new code
Linter not foundCheck golangci-lint linters — linter may need a newer version
Conflicts between lintersDisable the less useful one with a comment explaining why
v1 config errors after upgradeRun golangci-lint migrate to convert config format
Slow on large reposReduce run.concurrency or exclude paths with linters.exclusions.paths / formatters.exclusions.paths

Parallelizing Legacy Codebase Cleanup

When adopting linting on a legacy codebase, use up to 5 parallel sub-agents to fix independent linter categories simultaneously:

  • Sub-agent 1: Run golangci-lint run --fix ./... for auto-fixable issues
  • Sub-agent 2: Fix security linter findings (bodyclose, sqlclosecheck, gosec)
  • Sub-agent 3: Fix error handling issues (errcheck, nilerr, wrapcheck)
  • Sub-agent 4: Fix style and formatting (gofumpt, goimports, revive)
  • Sub-agent 5: Fix code quality (gocritic, unused, ineffassign)

Cross-References

  • → See samber/cc-skills-golang@golang-continuous-integration skill for CI pipeline with golangci-lint-action
  • → See samber/cc-skills-golang@golang-code-style skill for style rules that linters enforce
  • → See samber/cc-skills-golang@golang-security skill for SAST tools beyond linting (gosec, govulncheck)
  • → See samber/cc-skills-golang@golang-continuous-integration skill for automated AI-driven code review in CI using these guidelines