golangci/golangci-lint · error
%s is a formatter
Error message
%s is a formatter
What it means
Linters.validateNoFormatters rejects any name in linters.enable or linters.disable that is actually a formatter. In golangci-lint v2, formatters were split out of linters, so configuring e.g. 'gofmt' under linters is an error rather than silently accepted.
Source
Thrown at pkg/config/linters.go:44
func (l *Linters) Validate() error {
validators := []func() error{
l.Exclusions.Validate,
l.validateNoFormatters,
}
for _, v := range validators {
if err := v(); err != nil {
return err
}
}
return nil
}
func (l *Linters) validateNoFormatters() error {
for _, n := range slices.Concat(l.Enable, l.Disable) {
if slices.Contains(getAllFormatterNames(), n) {
return fmt.Errorf("%s is a formatter", n)
}
}
return nil
}
func getAllFormatterNames() []string {
return []string{"gci", "gofmt", "gofumpt", "goimports", "golines", "swaggo"}
}
View on GitHub (pinned to ed7a235d2d)
Solutions
- Move formatter names from linters.enable to formatters.enable
- Remove formatter names from linters.disable and use formatters settings instead
- Run 'golangci-lint migrate' to auto-convert a v1 config to v2
Example fix
# before
linters:
enable:
- gofmt
- revive
# after
linters:
enable:
- revive
formatters:
enable:
- gofmt Defensive patterns
Strategy: validation
Validate before calling
formatterNames := getAllFormatterNames()
for _, n := range slices.Concat(cfg.Linters.Enable, cfg.Linters.Disable) {
if slices.Contains(formatterNames, n) {
return fmt.Errorf("%s is a formatter; move it to formatters", n)
}
} Try / catch
if err := linters.Validate(); err != nil { log.Fatalf("linters config: %v", err) } Prevention
- After upgrading to v2, run 'golangci-lint migrate' on old configs
- Never list gofmt/goimports/gofumpt under linters
- Use 'golangci-lint config verify' in CI
When it happens
Trigger: v1-style config where gofmt/goimports/gofumpt etc. are listed under linters.enable or linters.disable; running golangci-lint v2 on an unmigrated config.
Common situations: Upgrading from golangci-lint v1 to v2 without running the migration; copy-pasting old configs; disabling a formatter via linters.disable.
Related errors
- %s is not a linter, it cannot be enabled or disabled
- at least %d of (text, source, path[-except], linters) should
- %s is not a formatter
- error in exclude rule #%d: %w
- invalid preset: %s
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/d64beb2c1a3b0825.
Report an issue: GitHub.