{"record":{"id":"81277acb6d15d4b9","repo":"golangci/golangci-lint","slug":"can-t-load-config-w-81277a","errorCode":null,"errorMessage":"can't load config: %w","messagePattern":"can't load config: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/migrate.go","lineNumber":180,"sourceCode":"\t\t}\n\n\t\tprintValidationDetail(cmd, v.DetailedOutput())\n\n\t\treturn errors.New(\"the configuration contains invalid elements\")\n\t}\n\n\treturn nil\n}\n\nfunc (c *migrateCommand) persistentPreRunE(_ *cobra.Command, args []string) error {\n\tc.log.Infof(\"%s\", c.buildInfo.String())\n\n\tloader := config.NewBaseLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, c.opts.LoaderOptions, fakeloader.NewConfig(), args)\n\n\t// Loads the configuration just to get the effective path of the configuration.\n\terr := loader.Load()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"can't load config: %w\", err)\n\t}\n\n\tsrcPath := c.viper.ConfigFileUsed()\n\tif srcPath == \"\" {\n\t\tc.log.Warnf(\"No config file detected\")\n\t\tos.Exit(exitcodes.NoConfigFileDetected)\n\t}\n\n\treturn fakeloader.Load(srcPath, c.cfg)\n}\n\nfunc (c *migrateCommand) backupConfigurationFile(srcPath string) error {\n\tfilename := strings.TrimSuffix(filepath.Base(srcPath), filepath.Ext(srcPath)) + \".bck\" + filepath.Ext(srcPath)\n\tdstPath := filepath.Join(filepath.Dir(srcPath), filename)\n\n\tc.log.Infof(\"Saving the v1 configuration to: %s\", dstPath)\n\n\tstat, err := os.Stat(srcPath)","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/migrate.go#L162-L198","documentation":"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.).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (.golangci.yml)\nlinters:\n  enable: govet  # must be a list\n# after\nlinters:\n  enable:\n    - govet","handlingStrategy":"validation","validationCode":"// pre-flight: confirm the config file exists and parses\nif _, err := os.Stat(cfgPath); err != nil {\n    return fmt.Errorf(\"config not found: %w\", err)\n}\nvar v map[string]any\nif err := yaml.Unmarshal(mustRead(cfgPath), &v); err != nil {\n    return fmt.Errorf(\"config parse error: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := loader.Load(); err != nil {\n    return fmt.Errorf(\"can't load config: %w\", err) // inspect wrapped cause: parse, unknown key, IO\n}","preventionTips":["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)."],"tags":["go","config","cli","config-loading"],"backgroundTag":"config-load-failed","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}