gohugoio/hugo · critical

failed to calculate hash for IntSets: %w

Error message

failed to calculate hash for IntSets: %w

What it means

While lazily computing a structural hash over the IntSets (language/version/role word sets) via hashing.Hash, the underlying hashstructure call returned an error. Because this runs inside a sync.Once initialization (initHash, vectorstores.go:705-712), Hugo panics rather than returning, treating it as an unrecoverable invariant violation. The hash is used for caching keyed off the dimension sets.

Source

Thrown at hugolib/sitesmatrix/vectorstores.go:710

		s.versions = hmaps.NewOrderedIntSet()
		for i := range cfg.ConfiguredVersions.ForEachIndex() {
			s.versions.Set(i)
		}
	}
	if s.roles == nil {
		s.roles = hmaps.NewOrderedIntSet()
		for i := range cfg.ConfiguredRoles.ForEachIndex() {
			s.roles.Set(i)
		}
	}
}

func (s *IntSets) initHash() {
	s.h.once.Do(func() {
		var err error
		s.h.hash, err = hashing.Hash(s.languages.Words(), s.versions.Words(), s.roles.Words())
		if err != nil {
			panic(fmt.Errorf("failed to calculate hash for IntSets: %w", err))
		}
	})
}

func (s *IntSets) init() *IntSets {
	return s
}

func (s *IntSets) setDimensionsFromOtherIfNotSet(other VectorIterator) {
	if other == nil {
		return
	}
	setLang := s.languages == nil
	setVer := s.versions == nil
	setRole := s.roles == nil

	if !(setLang || setVer || setRole) {
		return

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Since this is a panic from internal state, report it as a Hugo bug with the stack trace and configuration.
  2. Check for recent changes to dimension population code (config.ConfiguredRoles/Languages/Versions) that could pass an unhashable value.
  3. As a temporary diagnostic, reduce the build to a single language/version/role to isolate which dimension's words trigger the failure.
  4. Update Hugo to the latest version in case the hashing issue is already fixed.
Defensive patterns

Strategy: try-catch

Validate before calling

// No user-facing guard; the panic comes from internal hashing.
// Defensive: ensure dimension word sets are non-nil and well-typed before init.
func validateIntSets(s *IntSets) error {
    if s.languages == nil || s.versions == nil || s.roles == nil {
        return fmt.Errorf("IntSets dimensions not fully initialized")
    }
    return nil
}

Try / catch

// Wrap internal calls in recover during development to capture the panic.
func safeInitHash(s *IntSets) (err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("initHash panic: %v", r)
        }
    }()
    s.initHash()
    return nil
}

Prevention

When it happens

Trigger: hashing.Hash fails on the word slices passed from s.languages/versions/roles.Words() — practically only if the hashing library cannot serialize a value (e.g. an unsupported type, cyclic structure, or a hash option misconfiguration). This is an internal failure, not a user-config error.

Common situations: A bug or regression in how dimension sets are populated (nil words, unexpected types); extremely rare under normal use; seen during development of new dimension types or after refactoring the IntSets population.

Related errors


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