golangci/golangci-lint · error

failed to create linter %q: %w

Error message

failed to create linter %q: %w

What it means

runForbidigo builds forbidigo patterns from the config and calls forbidigo.NewLinter; any failure constructing the linter is wrapped as 'failed to create linter %q'. This means one or more configured patterns/options are invalid for the forbidigo library.

Source

Thrown at pkg/golinters/forbidigo/forbidigo.go:58

		// disable "//permit" directives so only "//nolint" directives matters within golangci-lint
		forbidigo.OptionIgnorePermitDirectives(true),
		forbidigo.OptionAnalyzeTypes(settings.AnalyzeTypes),
	}

	// Convert patterns back to strings because that is what NewLinter accepts.
	var patterns []string
	for _, pattern := range settings.Forbid {
		buffer, err := yaml.Marshal(pattern)
		if err != nil {
			return err
		}

		patterns = append(patterns, string(buffer))
	}

	forbid, err := forbidigo.NewLinter(patterns, options...)
	if err != nil {
		return fmt.Errorf("failed to create linter %q: %w", linterName, err)
	}

	for _, file := range pass.Files {
		runConfig := forbidigo.RunConfig{
			Fset:     pass.Fset,
			DebugLog: logutils.Debug(logutils.DebugKeyForbidigo),
		}

		if settings.AnalyzeTypes {
			runConfig.TypesInfo = pass.TypesInfo
		}

		hints, err := forbid.RunWithConfig(runConfig, file)
		if err != nil {
			return fmt.Errorf("forbidigo linter failed on file %q: %w", file.Name.String(), err)
		}

		for _, hint := range hints {

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Validate each forbidigo pattern as a regex (go run with regexp.Compile or an online tester) and fix syntax errors
  2. Upgrade golangci-lint/forbidigo if you use struct patterns or inline '# comment' syntax unsupported by the bundled version
  3. Reduce the pattern list to isolate the offending entry, then fix it
  4. Escape special regex characters in the identifiers you intend to forbid

Example fix

# before
forbidigo:
  forbid:
    - 'fmt\.Print('
# after
forbidigo:
  forbid:
    - '^fmt\.Print.*$'
Defensive patterns

Strategy: validation

Validate before calling

import "regexp"
for _, p := range cfg.Forbidigo.Forbid {
    pat := p
    if i := strings.Index(pat, "# "); i >= 0 { // struct-pattern comment
        pat = pat[:i]
    }
    if _, err := regexp.Compile(strings.TrimSuffix(pat, ":*")); err != nil {
        return fmt.Errorf("invalid forbidigo pattern %q: %w", p, err)
    }
}

Try / catch

if err := golangci.Run(); err != nil {
    if strings.Contains(err.Error(), "failed to create linter") {
        fmt.Fprintln(os.Stderr, "fix linters-settings.forbidigo.forbid regex patterns")
        os.Exit(1)
    }
    return err
}

Prevention

When it happens

Trigger: A forbidigo pattern in settings.forbidigo.forbid is not a valid regular expression (or a valid struct pattern like 'fmt.Print*:*# comment' when analyze-types/pattern syntax is on), or invalid options (e.g. bad msg/config keys) are passed to forbidigo.NewLinter.

Common situations: Hand-written patterns with unbalanced regex groups like 'fmt\.Print(', patterns copied from docs for a different forbidigo version (struct pattern syntax introduced in forbidigo v1.5/v2), or comments embedded in patterns with an older forbidigo that doesn't support them.

Related errors


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