配置未生效主因是路径、缩进、字段层级三处硬性约束不符:文件名必须为.golangci.yml且与go.mod同级;所有顶层字段需顶格平级、仅用空格缩进;linters-settings等不可嵌套于linters内。

配置文件存在但 golangci-lint run 完全没反应,或报错却找不到原因?大概率不是语法写错,而是路径、缩进、字段层级这三处被忽略的硬性约束出了问题。
配置文件名和位置必须严格匹配 .golangci.yml
golangci-lint 只认 .golangci.yml(点开头 + yml 小写),其他任何变体都会静默跳过:
- ❌ .golangci.yaml、golangci.yml、.golangci.yml.bak 都无效
- ❌ 文件放在 config/、tools/ 或子模块目录下,即使有 go.mod 也不加载
- ✅ 必须与项目根目录的 go.mod 处于同一级目录
- ✅ 多 module 项目(如 api/ 和 shared/)需各自目录下都放一份 .golangci.yml
- CI 脚本中不能依赖自动发现,必须显式传参:golangci-lint run --config=.golangci.yml
YAML 缩进和顶层字段层级不能错一格
所有顶层字段(run、linters、linters-settings、output)必须顶格、平级,且缩进只能用空格:
- ❌ linters-settings 写成 linters 的子项(即多缩进两格)→ 整个配置被忽略
- ❌ 用了 Tab 替代空格,或冒号后少空格(如 enable:- gofmt 缺少空格)→ 静默失效
- ❌ enable 列表项前漏了 - 或换行错位 → 解析失败,退回到默认启用集(仅 govet、errcheck 等)
- 推荐用 yamllint .golangci.yml 验证基础语法;注意复制网上示例时可能带入不可见字符(如 Zero Width Space)
exhaustive 检查器升级后字段名和值格式全变了
从 golangci-lint v2.15 开始,exhaustive 的配置字段彻底重构,旧写法不报错但完全不生效:
- ❌ explicit-exhaustive-switch 和 explicit-exhaustive-map 已废弃,统一为 explicit-exhaustive
- ❌ check: map 必须改为 check: mapliteral(也支持 switch、typeswitch)
- ❌ ignore-enum-members: Unknown 必须改为 ignore-constants: ["Unknown"](值必须是字符串切片)
- ❌ ignore-enum-types 改为 ignore-types,同样要求切片格式
- CI 中若启用了 --fast,exhaustive 会被跳过(它属于 slow 分组),本地无感但 CI 不报错
CI 报 “package xxx not in GOROOT” 不是 lint 问题,是 Go 环境没准备好
这类错误本质是 golangci-lint 在调用 go list -json 构建 AST 时失败,常见于:
- Go 版本低于 1.22(cmp、slices、maps、log/slog、go/version 均未进入标准库)
- GO111MODULE=off 或未设置,导致 module 模式未启用
- go.mod 未提交到 Git,CI 拉不到;或用了 replace 指向本地路径但 CI 未同步
- 修复顺序必须是:go mod tidy → go build ./ → 再跑 golangci-lint run;CI 脚本里别省掉前两步
真正卡住人的从来不是怎么写配置,而是工具对路径、缩进、Go 版本这些“基础设施层”的苛刻要求——它不会告诉你哪错了,只会安静地退回到最保守的默认行为。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











