{"record":{"id":"62f5eafc1419d149","repo":"golangci/golangci-lint","slug":"configuration-version-is-already-set-s","errorCode":null,"errorMessage":"configuration version is already set: %s","messagePattern":"configuration version is already set: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/migrate.go","lineNumber":142,"sourceCode":"\t}\n\n\tc.log.Infof(\"Migration done: %s\", dstPath)\n\n\tcallForAction(c.cmd)\n\n\treturn nil\n}\n\nfunc (c *migrateCommand) preRunE(cmd *cobra.Command, _ []string) error {\n\tswitch strings.ToLower(c.opts.format) {\n\tcase \"\", \"yml\", \"yaml\", \"toml\", \"json\":\n\t\t// Valid format.\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported format: %s\", c.opts.format)\n\t}\n\n\tif c.cfg.Version != \"\" {\n\t\treturn fmt.Errorf(\"configuration version is already set: %s\", c.cfg.Version)\n\t}\n\n\tif c.opts.skipValidation {\n\t\treturn nil\n\t}\n\n\tusedConfigFile := c.viper.ConfigFileUsed()\n\tif usedConfigFile == \"\" {\n\t\tc.log.Warnf(\"No config file detected\")\n\t\tos.Exit(exitcodes.NoConfigFileDetected)\n\t}\n\n\tc.log.Infof(\"Validating v1 configuration file: %s\", usedConfigFile)\n\n\terr := validateConfiguration(jsonsch.V1Schema, usedConfigFile)\n\tif err != nil {\n\t\tvar v *jsonschema.ValidationError\n\t\tif !errors.As(err, &v) {","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/migrate.go#L124-L160","documentation":"The migrate command refuses to run when the loaded configuration already has a version set, i.e. it is not a plain v1 config. Migration targets unversioned/v1 configs; a config that already declares `version: \"2\"` (or similar) is not something migrate can convert. This check happens in `preRunE` after format validation.","triggerScenarios":"Running `golangci-lint migrate` against a config file that already contains a `version:` key (e.g. it was already migrated to v2), so `c.cfg.Version` is non-empty.","commonSituations":"Running migrate twice on the same repo; pointing migrate at a `.golangci.yml` already migrated by a teammate; a config template that ships with `version: \"2\"` already set.","solutions":["Don't migrate — the config is already versioned; use it as-is.","If you truly want a fresh migration, remove the `version:` line from the config file first (only if it is a v1-shaped config).","Restore the original v1 config from version control before running migrate."],"exampleFix":"# before (.golangci.yml)\nversion: \"2\"\nlinters:\n  enable: [govet]\n# after (original v1 config)\nlinters:\n  enable:\n    - govet","handlingStrategy":"validation","validationCode":"// check the config for a version key before migrating\ndata, _ := os.ReadFile(\".golangci.yml\")\nif strings.Contains(string(data), \"version:\") {\n    return errors.New(\"config already declares a version; migration not needed\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run migrate only once per config; version it in git afterward.","Check the config head for `version:` before re-running migrate.","Keep already-migrated v2 configs out of migrate workflows.","Restore the original v1 config from VCS if you need to re-migrate."],"tags":["go","cli","config","config-migration"],"backgroundTag":"config-already-migrated","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}