gohugoio/hugo · error

version name cannot be empty

Error message

version name cannot be empty

What it means

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.

Solutions

  1. Inspect the [versions] section of hugo.toml and remove/rename any [versions.""] entry.
  2. Give every version a non-empty identifier, e.g. [versions.v1] and [versions.v2].
  3. Run hugo config to print the resolved versions map and locate the empty key.

Example fix

// before
[versions]
[versions.""]
weight = 1
// after
[versions.v1]
weight = 1
Defensive patterns

Strategy: validation

Validate before calling

// Before building config, reject empty version keys.
for k := range versionConfigs {
    if k == "" { return errors.New("remove empty version key") }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/9254f5c7e01d7c71. Report an issue: GitHub.

Appendix: source

Thrown at hugolib/versions/versions.go:165

const defaultContentVersionFallback = "v1.0.0"

func (r *VersionsInternal) init(defaultContentVersion string) error {
	if r.versionConfigs == nil {
		r.versionConfigs = make(map[string]VersionConfig)
	}
	defaultContentVersionProvided := defaultContentVersion != ""
	if len(r.versionConfigs) == 0 {
		if defaultContentVersion == "" {
			defaultContentVersion = defaultContentVersionFallback
		}
		// Add a default version.
		r.versionConfigs[defaultContentVersion] = VersionConfig{}
	}

	var defaultSeen bool
	for k, v := range r.versionConfigs {
		if k == "" {
			return errors.New("version name cannot be empty")
		}
		if err := paths.ValidateIdentifier(k); err != nil {
			return fmt.Errorf("version name %q is invalid: %s", k, err)
		}

		var isDefault bool
		if k == defaultContentVersion {
			isDefault = true
			defaultSeen = true
		}

		// Ignore error, this may not be a semver version.
		parsedVersion, _ := version.ParseVersion(k)

		r.Sorted = append(r.Sorted, VersionInternal{Name: k, parsedVersion: parsedVersion, Default: isDefault, VersionConfig: v})
	}

	// Sort by weight if set, then semver descending.

View on GitHub (pinned to 52c9bd7908)