golangci/golangci-lint · error

invalid formatter %q

Error message

invalid formatter %q

What it means

NewMetaFormatter validates every name in the formatters.enable config list via IsFormatter and rejects the first one it does not recognize. It means golangci-lint was asked to enable a formatter that either does not exist or is not registered in this build.

Source

Thrown at pkg/goformatters/meta_formatter.go:27

	"github.com/golangci/golangci-lint/v2/pkg/config"
	"github.com/golangci/golangci-lint/v2/pkg/goformatters/gci"
	"github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt"
	"github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt"
	"github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports"
	"github.com/golangci/golangci-lint/v2/pkg/goformatters/golines"
	"github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo"
	"github.com/golangci/golangci-lint/v2/pkg/logutils"
)

type MetaFormatter struct {
	log        logutils.Log
	formatters []Formatter
}

func NewMetaFormatter(log logutils.Log, cfg *config.Formatters, runCfg *config.Run) (*MetaFormatter, error) {
	for _, formatter := range cfg.Enable {
		if !IsFormatter(formatter) {
			return nil, fmt.Errorf("invalid formatter %q", formatter)
		}
	}

	m := &MetaFormatter{log: log}

	if slices.Contains(cfg.Enable, gofmt.Name) {
		m.formatters = append(m.formatters, gofmt.New(&cfg.Settings.GoFmt))
	}

	if slices.Contains(cfg.Enable, gofumpt.Name) {
		m.formatters = append(m.formatters, gofumpt.New(&cfg.Settings.GoFumpt, runCfg.Go))
	}

	if slices.Contains(cfg.Enable, goimports.Name) {
		m.formatters = append(m.formatters, goimports.New(&cfg.Settings.GoImports))
	}

	if slices.Contains(cfg.Enable, swaggo.Name) {

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Run 'golangci-lint formatters' to list valid formatter names and correct the typo in formatters.enable
  2. Upgrade golangci-lint if the formatter exists only in a newer release
  3. Remove the unsupported formatter from formatters.enable
  4. For custom formatters, build golangci-lint with the plugin properly registered

Example fix

# before
formatters:
  enable:
    - gofumptt
# after
formatters:
  enable:
    - gofumpt
Defensive patterns

Strategy: validation

Validate before calling

// Before writing config, verify each formatter name is known:
// golangci-lint formatters   # list valid formatter names
const validFormatters = map[string]bool{"gofmt": true, "gofumpt": true, "gci": true, "goimports": true, "golines": true}
for _, f := range cfg.Formatters.Enable {
    if !validFormatters[f] {
        return fmt.Errorf("unknown formatter %q — see 'golangci-lint formatters'", f)
    }
}

Try / catch

if err := runner.New(); err != nil {
    var cfgErr *configError
    if strings.Contains(err.Error(), "invalid formatter") {
        fmt.Fprintln(os.Stderr, "fix formatters.enable in .golangci.yml; run 'golangci-lint formatters' for names")
        os.Exit(1)
    }
    return err
}

Prevention

When it happens

Trigger: A formatters.enable entry in .golangci.yml (e.g. 'prettier', a misspelled 'gofumpt', or a plugin formatter) that IsFormatter does not know. Called from preRunE / NewRunner during startup.

Common situations: Typo in the enable list, copying config from another tool (gofmt vs gofumps), using a formatter added in a newer golangci-lint version than installed, or expecting a custom plugin formatter to be auto-registered without a plugin build.

Related errors


AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02). Data as JSON: /api/errors/508183456764ed22. Report an issue: GitHub.