golang-lint
samber/cc-skills-golang
Configure golangci-lint, interpret lint output, and suppress warnings in Go projects.
What is golang-lint?
This skill provides linting best practices and golangci-lint configuration for Go projects. Use it when setting up code quality tooling, configuring .golangci.yml, interpreting lint warnings, writing nolint directives, or choosing which linters to enable.
- Run golangci-lint with parallel linting across 100+ aggregated linters
- Configure .golangci.yml with production-ready settings (33+ linters enabled)
- Auto-fix issues where possible using golangci-lint --fix
- Suppress specific lint warnings with justified //nolint directives
- Interpret lint output and map issues to their source linters
- Parallelize legacy codebase cleanup across independent linter categories
How to install golang-lint
npx skills add https://github.com/samber/cc-skills-golang --skill golang-lint- golangci-lint binary installed (via brew, go install, or package manager)
- Go toolchain installed and working
- Existing Go project or module
How to use golang-lint
- 1.Install golangci-lint if not already present: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
- 2.Create or update .golangci.yml in your project root with desired linter configuration
- 3.Run golangci-lint run ./... to check all code against configured linters
- 4.Use golangci-lint run --fix ./... to auto-fix issues where possible
- 5.For lint warnings that cannot be auto-fixed, add //nolint:linter-name // justification comments
- 6.Run golangci-lint fmt ./... to format code before committing
- 7.Add lint targets to your Makefile (lint, lint-fix, fmt) for team consistency
Use cases
- Setting up golangci-lint in a new Go project with a production-ready .golangci.yml
- Fixing lint warnings on existing code and writing proper nolint suppressions
- Adopting linting incrementally on legacy codebases using new-from-rev
- Troubleshooting linter conflicts, timeouts, or performance issues
- Integrating golangci-lint into CI/CD pipelines
- Go developers setting up code quality tooling
- Teams adopting linting on legacy Go projects
- Code reviewers interpreting lint output
- DevOps engineers configuring CI pipelines with linting
golang-lint FAQ
//nolint suppresses all linters on a line (bad practice). //nolint:linter-name suppresses only a specific linter and is required by the nolintlint linter. Always use the specific form with a justification comment.
Avoid suppressing security linters (gosec, bodyclose, sqlclosecheck) unless absolutely necessary. If you must suppress, use //nolint:gosec // detailed justification explaining the security risk and mitigation. Document the decision in code review.
Increase run.timeout in .golangci.yml (golangci-lint v2 defaults to no timeout). For large repos, reduce run.concurrency or exclude slow paths with linters.exclusions.paths. Use golangci-lint run --verbose to identify which linters are slow.
Set issues.new-from-rev: HEAD~1 in .golangci.yml to lint only code changed since the last commit. This lets you adopt linting incrementally without fixing the entire legacy codebase at once.
Yes, use golangci-lint run --enable-only linter-name ./... to run only one linter. Use golangci-lint linters to see all available linters and their descriptions.
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." user-invocable: true license: MIT compatibility: Designed for Claude Code or similar AI coding agents, and for projects using Golang. metadata: author: samber version: "1.2.2" 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
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.
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 (via the Agent tool) 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-code-style
Go code style conventions for clarity, control flow, and readability—line breaking, variable declarations, and when comments help.
golang-error-handling
Idiomatic Go error handling: wrapping, inspection, structured logging, and production-grade error tracking.
golang-performance
Go performance optimization patterns: identify bottlenecks with profiling, then apply the right fix.
golang-design-patterns
Idiomatic Go design patterns: functional options, constructors, error handling, resource lifecycle, graceful shutdown, and resilience.
golang-testing
Production-ready Go tests with table-driven patterns, testify integration, parallel execution, fuzzing, and leak detection.
golang-security
Security best practices and vulnerability prevention for Go code—injection, crypto, secrets, and authentication.