golangci/golangci-lint · error
custom linter %q: %w
Error message
custom linter %q: %w
What it means
During LintersSettings validation, each entry in settings.custom is validated; a failure is wrapped as 'custom linter %q: %w' with the plugin's name. This means a user-defined (plugin) linter's settings block — typically its path and type — is invalid.
Source
Thrown at pkg/config/linters_settings.go:355
UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"`
UseTesting UseTestingSettings `mapstructure:"usetesting"`
Varnamelen VarnamelenSettings `mapstructure:"varnamelen"`
Whitespace WhitespaceSettings `mapstructure:"whitespace"`
Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"`
WSL WSLv4Settings `mapstructure:"wsl"` // Deprecated: use WSLv5 instead.
WSLv5 WSLv5Settings `mapstructure:"wsl_v5"`
Custom map[string]CustomLinterSettings `mapstructure:"custom"`
}
func (s *LintersSettings) Validate() error {
if err := s.Govet.Validate(); err != nil {
return err
}
for name, settings := range s.Custom {
if err := settings.Validate(); err != nil {
return fmt.Errorf("custom linter %q: %w", name, err)
}
}
return nil
}
type AsasalintSettings struct {
Exclude []string `mapstructure:"exclude"`
UseBuiltinExclusions bool `mapstructure:"use-builtin-exclusions"`
}
type BiDiChkSettings struct {
LeftToRightEmbedding bool `mapstructure:"left-to-right-embedding"`
RightToLeftEmbedding bool `mapstructure:"right-to-left-embedding"`
PopDirectionalFormatting bool `mapstructure:"pop-directional-formatting"`
LeftToRightOverride bool `mapstructure:"left-to-right-override"`
RightToLeftOverride bool `mapstructure:"right-to-left-override"`
LeftToRightIsolate bool `mapstructure:"left-to-right-isolate"`View on GitHub (pinned to ed7a235d2d)
Solutions
- Read the wrapped inner error for the exact field problem on the named custom linter
- Set the required keys (path and type) in linters.settings.custom.<name>
- Rebuild the plugin .so with the matching golangci-lint version and fix the path
Example fix
# before
linters:
settings:
custom:
mylinter:
type: module
# after
linters:
settings:
custom:
mylinter:
path: ./plugin/mylinter.so
type: plugin Defensive patterns
Strategy: validation
Validate before calling
for name, s := range cfg.Linters.Settings.Custom {
if s.Path == "" {
return fmt.Errorf("custom linter %q: path is required", name)
}
if _, err := os.Stat(s.Path); err != nil {
return fmt.Errorf("custom linter %q: plugin not found: %w", name, err)
}
} Try / catch
if err := settings.Validate(); err != nil {
log.Fatalf("custom linter config: %v", err)
} Prevention
- Always set both path and type for custom linters
- Build plugin .so files with the exact golangci-lint version in use
- Check plugin paths are relative to config dir or absolute as documented
When it happens
Trigger: Config linters.settings.custom.<name> missing required fields (e.g. no 'path' to the plugin .so, bad 'type'), or the referenced plugin file failing the inner validation.
Common situations: Custom plugin path typo or .so not built; using module plugin type without a valid module path; upgrading plugins after golangci-lint version change.
Related errors
- update plugin file: %w
- can't get enabled linters: %w
- at least %d of (text, source, path[-except], linters) should
- %s is not a formatter
- %s is a formatter
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/8cbceede9dc76d49.
Report an issue: GitHub.