golangci/golangci-lint · error
can't load config: %w
Error message
can't load config: %w
What it means
The config command's preRunE builds a default config and uses config.NewLintersLoader to load and process the user's configuration. Any failure from loader.Load(config.LoadOptions{}) — parsing, validation, or linters-settings resolution — is wrapped as "can't load config: %w".
Source
Thrown at pkg/commands/config.go:97
pathFlagSet := pathCommand.Flags()
pathFlagSet.BoolVar(&c.pathOpts.JSON, "json", false, color.GreenString("Display as JSON"))
c.cmd = configCmd
return c
}
func (c *configCommand) preRunE(cmd *cobra.Command, args []string) error {
// The command doesn't depend on the real configuration.
// It only needs to know the path of the configuration file.
cfg := config.NewDefault()
loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts, cfg, args)
err := loader.Load(config.LoadOptions{})
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
return nil
}
func (c *configCommand) executePath(cmd *cobra.Command, _ []string) error {
usedConfigFile := c.getUsedConfig()
if c.pathOpts.JSON {
abs, err := filepath.Abs(usedConfigFile)
if err != nil {
return err
}
return json.NewEncoder(cmd.OutOrStdout()).Encode(map[string]string{
"path": usedConfigFile,
"absolutePath": abs,
})View on GitHub (pinned to ed7a235d2d)
Solutions
- Inspect the wrapped %w error for the precise problem (line number in YAML, unknown key, unknown linter) and fix the config accordingly
- Run the config verify subcommand (JSON Schema validation) to pinpoint invalid config elements
- Confirm the config file path is correct and readable from the current working directory
- If the config comes from an older release, migrate it to the current schema (check the changelog for renamed options)
Example fix
# before (.golangci.yml)
linters:
enable:
- lll
settings:
lll: { lin-length: 120 } # unknown key
# after
linters:
enable:
- lll
settings:
lll:
line-length: 120 Defensive patterns
Strategy: validation
Validate before calling
func validateConfigBeforeLoad(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("config unreadable: %w", err)
}
var v map[string]any
if err := yaml.Unmarshal(data, &v); err != nil {
return fmt.Errorf("config is not valid YAML: %w", err)
}
return nil // then run `golangci-lint config verify` for schema-level checks
} Type guard
var loadErr *config.LoadError // or inspect wrapped causes
if errors.As(err, &target) {
switch {
case errors.Is(err, os.ErrNotExist): // wrong path
case strings.Contains(err.Error(), "unknown"): // unknown linter/key
}
} Try / catch
if err := loader.Load(config.LoadOptions{}); err != nil {
if strings.Contains(err.Error(), "unknown") || strings.Contains(err.Error(), "unmarshal") {
log.Fatalf("config problem, run 'golangci-lint config verify' for details: %v", err)
}
return fmt.Errorf("can't load config: %w", err)
} Prevention
- Run `config verify` (JSON Schema check) after every config edit or in CI
- Start from the documented example config and change incrementally
- Keep config file at a well-known path (.golangci.yml) to avoid path mistakes
- After upgrading the tool, review the changelog for renamed/removed settings and update the config
When it happens
Trigger: Invoking any config subcommand (e.g. `config path`) whose preRunE calls loader.Load, when the YAML/JSON config file is malformed or references unknown linters/settings.
Common situations: Typo in a config key or linter name; invalid YAML/JSON syntax (bad indentation, tabs); config file path wrong or unreadable; config written for an older/newer version with incompatible options.
Related errors
- [%s] validate: %w
- the configuration contains invalid elements
- root field 'version' is required
- no plugins defined
- field 'module' is required
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/3e2d5aa8f2187a47.
Report an issue: GitHub.