{"record":{"id":"9254f5c7e01d7c71","repo":"gohugoio/hugo","slug":"version-name-cannot-be-empty","errorCode":null,"errorMessage":"version name cannot be empty","messagePattern":"version name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hugolib/versions/versions.go","lineNumber":165,"sourceCode":"const defaultContentVersionFallback = \"v1.0.0\"\n\nfunc (r *VersionsInternal) init(defaultContentVersion string) error {\n\tif r.versionConfigs == nil {\n\t\tr.versionConfigs = make(map[string]VersionConfig)\n\t}\n\tdefaultContentVersionProvided := defaultContentVersion != \"\"\n\tif len(r.versionConfigs) == 0 {\n\t\tif defaultContentVersion == \"\" {\n\t\t\tdefaultContentVersion = defaultContentVersionFallback\n\t\t}\n\t\t// Add a default version.\n\t\tr.versionConfigs[defaultContentVersion] = VersionConfig{}\n\t}\n\n\tvar defaultSeen bool\n\tfor k, v := range r.versionConfigs {\n\t\tif k == \"\" {\n\t\t\treturn errors.New(\"version name cannot be empty\")\n\t\t}\n\t\tif err := paths.ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"version name %q is invalid: %s\", k, err)\n\t\t}\n\n\t\tvar isDefault bool\n\t\tif k == defaultContentVersion {\n\t\t\tisDefault = true\n\t\t\tdefaultSeen = true\n\t\t}\n\n\t\t// Ignore error, this may not be a semver version.\n\t\tparsedVersion, _ := version.ParseVersion(k)\n\n\t\tr.Sorted = append(r.Sorted, VersionInternal{Name: k, parsedVersion: parsedVersion, Default: isDefault, VersionConfig: v})\n\t}\n\n\t// Sort by weight if set, then semver descending.","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/hugolib/versions/versions.go#L147-L183","documentation":"Thrown by VersionsInternal.init in hugolib/versions/versions.go:165 when the versionConfigs map contains the empty-string key. Hugo's content-versions feature keys each version by name; an empty key is rejected before semver parsing/sorting.","triggerScenarios":"Configuring [versions] with an empty-key sub-table (e.g. [versions.\"\"]), or programmatically building a versions config map containing the \"\" key. init runs during site matrix construction.","commonSituations":"Malformed TOML/YAML under [versions], a config template that emits a blank version key, or a typo producing a quoted-empty key. A default version (\"v1.0.0\") is auto-added when none are configured, so this fires only on an explicit empty key.","solutions":["Inspect the [versions] section of hugo.toml and remove/rename any [versions.\"\"] entry.","Give every version a non-empty identifier, e.g. [versions.v1] and [versions.v2].","Run hugo config to print the resolved versions map and locate the empty key."],"exampleFix":"// before\n[versions]\n[versions.\"\"]\nweight = 1\n// after\n[versions.v1]\nweight = 1","handlingStrategy":"validation","validationCode":"// Before building config, reject empty version keys.\nfor k := range versionConfigs {\n    if k == \"\" { return errors.New(\"remove empty version key\") }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the [versions] table with hugo config before building.","Never emit a [versions.\"\"] entry from config generators.","Treat an empty version key as a config-generation bug."],"tags":["config","versions","validation"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}