{"record":{"id":"b721de8082abbab5","repo":"golangci/golangci-lint","slug":"root-field-version-is-required","errorCode":null,"errorMessage":"root field 'version' is required","messagePattern":"root field 'version' is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/internal/configuration.go","lineNumber":35,"sourceCode":"// Configuration represents the configuration file.\ntype Configuration struct {\n\t// golangci-lint version.\n\tVersion string `yaml:\"version\"`\n\n\t// Name of the binary.\n\tName string `yaml:\"name,omitempty\"`\n\n\t// Destination is the path to a directory to store the binary.\n\tDestination string `yaml:\"destination,omitempty\"`\n\n\t// Plugins information.\n\tPlugins []*Plugin `yaml:\"plugins,omitempty\"`\n}\n\n// Validate checks and clean the configuration.\nfunc (c *Configuration) Validate() error {\n\tif strings.TrimSpace(c.Version) == \"\" {\n\t\treturn errors.New(\"root field 'version' is required\")\n\t}\n\n\tif strings.TrimSpace(c.Name) == \"\" {\n\t\tc.Name = defaultBinaryName\n\t}\n\n\tif len(c.Plugins) == 0 {\n\t\treturn errors.New(\"no plugins defined\")\n\t}\n\n\tfor _, plugin := range c.Plugins {\n\t\tif strings.TrimSpace(plugin.Module) == \"\" {\n\t\t\treturn errors.New(\"field 'module' is required\")\n\t\t}\n\n\t\tif strings.TrimSpace(plugin.Import) == \"\" {\n\t\t\tplugin.Import = plugin.Module\n\t\t}","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/internal/configuration.go#L17-L53","documentation":"`Configuration.Validate` (pkg/commands/internal/configuration.go:35) requires the root `version` field of a `.custom-gcl.*` (custom golangci-lint builder) configuration to be a non-blank string. This field pins which golangci-lint release the custom binary is built from; without it the builder cannot resolve a base version, so validation fails immediately. Empty/whitespace-only values are rejected via `strings.TrimSpace`.","triggerScenarios":"Loading and validating a `.custom-gcl.yml` (or .yaml/.json) file whose top-level `version:` key is absent, empty (`version: \"\"`), or whitespace only, before running the custom binary build.","commonSituations":"Creating a fresh plugin config with only the `plugins` section; deleting the version line during refactoring; a template that left `version:` with no value; YAML key typo like `versions:` or `Version:` that silently decodes as empty.","solutions":["Add a `version` field at the root of the .custom-gcl config file pinning a golangci-lint release, e.g. `version: v2.1.6`","Check for YAML key typos/indentation so the value actually lands in the `version` field","Re-create the config from the custom-gcl documentation template, then fill in your plugins"],"exampleFix":"# before (.custom-gcl.yml)\nplugins:\n  - module: github.com/me/my-plugin\n    version: v1.0.0\n# after\nversion: v2.1.6\nplugins:\n  - module: github.com/me/my-plugin\n    version: v1.0.0","handlingStrategy":"validation","validationCode":"cfg, err := yaml.Marshal(map[string]any{\n\t\"version\": \"v2.1.6\",\n\t\"plugins\": []any{\n\t\tmap[string]any{\"module\": \"github.com/me/my-plugin\", \"version\": \"v1.0.0\"},\n\t},\n})\n_ = os.WriteFile(\".custom-gcl.yml\", cfg, 0o644)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include a root `version:` pinning a golangci-lint release in .custom-gcl configs","Check for YAML key typos and indentation when the value seems set but decodes empty","Start from the documented custom-gcl template instead of a blank file"],"tags":["custom-gcl","config","validation","required-field"],"backgroundTag":"missing-required-config-field","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}