golangci/golangci-lint · error
can't load config: %w
Error message
can't load config: %w
What it means
In migrate's `persistentPreRunE`, the configuration is loaded once just to discover the effective config file path. If the loader fails for any reason, the error is wrapped as `can't load config: %w`. The root cause is in the wrapped error (parse error, unknown keys with strict mode, unreadable file, etc.).
Source
Thrown at pkg/commands/migrate.go:180
}
printValidationDetail(cmd, v.DetailedOutput())
return errors.New("the configuration contains invalid elements")
}
return nil
}
func (c *migrateCommand) persistentPreRunE(_ *cobra.Command, args []string) error {
c.log.Infof("%s", c.buildInfo.String())
loader := config.NewBaseLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, c.opts.LoaderOptions, fakeloader.NewConfig(), args)
// Loads the configuration just to get the effective path of the configuration.
err := loader.Load()
if err != nil {
return fmt.Errorf("can't load config: %w", err)
}
srcPath := c.viper.ConfigFileUsed()
if srcPath == "" {
c.log.Warnf("No config file detected")
os.Exit(exitcodes.NoConfigFileDetected)
}
return fakeloader.Load(srcPath, c.cfg)
}
func (c *migrateCommand) backupConfigurationFile(srcPath string) error {
filename := strings.TrimSuffix(filepath.Base(srcPath), filepath.Ext(srcPath)) + ".bck" + filepath.Ext(srcPath)
dstPath := filepath.Join(filepath.Dir(srcPath), filename)
c.log.Infof("Saving the v1 configuration to: %s", dstPath)
stat, err := os.Stat(srcPath)View on GitHub (pinned to ed7a235d2d)
Solutions
- Read the wrapped error after 'can't load config:' — it names the offending file/key.
- Fix YAML/JSON syntax errors in the config file.
- Remove or correct unknown/deprecated keys flagged by the loader.
- Verify the config path with `golangci-lint config path` and pass --config explicitly if multiple configs exist.
Example fix
# before (.golangci.yml)
linters:
enable: govet # must be a list
# after
linters:
enable:
- govet Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm the config file exists and parses
if _, err := os.Stat(cfgPath); err != nil {
return fmt.Errorf("config not found: %w", err)
}
var v map[string]any
if err := yaml.Unmarshal(mustRead(cfgPath), &v); err != nil {
return fmt.Errorf("config parse error: %w", err)
} Try / catch
if err := loader.Load(); err != nil {
return fmt.Errorf("can't load config: %w", err) // inspect wrapped cause: parse, unknown key, IO
} Prevention
- Fix the root cause reported after 'can't load config:' first.
- Run `golangci-lint config verify` before CI runs.
- Keep one canonical config per repo and pass --config explicitly.
- Remove unknown/deprecated keys flagged by the loader.
- Pin the config schema to your golangci-lint major version (v1 vs v2).
When it happens
Trigger: Running `golangci-lint migrate` when the config file at the discovered path cannot be loaded: syntax errors, invalid values failing strict decoding, unreadable file, or an environment/config search issue producing a bad path.
Common situations: Corrupted or hand-edited .golangci.yml; deprecated or unknown keys in strict mode; config referencing env vars that aren't set; wrong CONFIG path via --config.
Related errors
- can't load config: %w
- configuration version is already set: %s
- can't load config: %w
- hash plugin directory: %w
- file %s not found: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/81277acb6d15d4b9.
Report an issue: GitHub.