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- 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)
How to use golang-lint
- 1.Install golangci-lint if not already present
- 2.Copy or generate a .golangci.yml configuration (use the recommended production-ready setup as a starting point)
- 3.Run golangci-lint run ./... to lint all Go files and review output
- 4.Use golangci-lint run --fix ./... to auto-fix issues where possible
- 5.For legacy codebases, set issues.new-from-rev in .golangci.yml to lint only new/changed code
- 6.Suppress remaining false positives with //nolint:linter-name // justification directives
- 7.Run golangci-lint fmt ./... before committing to format code
- 8.Add lint and lint-fix targets to your Makefile for team consistency
Use cases
- 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
- 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
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.
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.
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.
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.
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 --fixon 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:
- //nolint directives MUST specify the linter name:
//nolint:errchecknot//nolint - //nolint directives MUST include a justification comment:
//nolint:errcheck // reason - The
nolintlintlinter enforces both rules above — it flags bare//nolintand missing reasons - 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
- Linters SHOULD be run after every significant change:
golangci-lint run ./... - Auto-fix what you can:
golangci-lint run --fix ./... - Format before committing:
golangci-lint fmt ./... - Incremental adoption on legacy code: set
issues.new-from-revin.golangci.ymlto 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 // reasonif it's a false positive - Use
golangci-lint run --verbosefor additional context and timing
Common Issues
| Problem | Solution |
|---|---|
| "deadline exceeded" | Set or increase run.timeout in .golangci.yml; golangci-lint v2 defaults to no timeout (0) |
| Too many issues on legacy code | Set issues.new-from-rev: HEAD~1 to lint only new code |
| Linter not found | Check golangci-lint linters — linter may need a newer version |
| Conflicts between linters | Disable the less useful one with a comment explaining why |
| v1 config errors after upgrade | Run golangci-lint migrate to convert config format |
| Slow on large repos | Reduce 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-integrationskill for CI pipeline with golangci-lint-action - → See
samber/cc-skills-golang@golang-code-styleskill for style rules that linters enforce - → See
samber/cc-skills-golang@golang-securityskill for SAST tools beyond linting (gosec, govulncheck) - → See
samber/cc-skills-golang@golang-continuous-integrationskill for automated AI-driven code review in CI using these guidelines
Related skills
More from samber/cc-skills-golang and the wider catalog.

golang-linter
Agent skill from samber/cc-skills-golang.

golang-modernize
Modernize Go code to use recent language features, standard library improvements, and idiomatic patterns.

golang-naming
Go naming conventions for packages, types, functions, errors, and identifiers.

golang-observability
Production observability for Go: structured logging, metrics, tracing, profiling, and RUM in one skill.

golang-performance
Go performance optimization patterns: identify bottlenecks via profiling, then apply the right optimization pattern.

golang-pkg-go-dev
Query pkg.go.dev for Go package docs, symbols, versions, vulnerabilities, and importers via godig CLI or MCP server.