gohugoio/hugo · error

invalid index type %q. Must be one of %v

Error message

invalid index type %q. Must be one of %v

What it means

Each entry in `related.indices` has a `type` controlling how its values are indexed; DecodeConfig lower-cases names, defaults an empty type to `basic`, and rejects anything not in validTypes (related/inverted_index.go:588-593). The error lists the valid types (`basic` and `fragments`) so the user can correct the config.

Source

Thrown at related/inverted_index.go:592

	if c.Threshold < 0 || c.Threshold > 100 {
		return Config{}, errors.New("related threshold must be between 0 and 100")
	}

	if c.ToLower {
		for i := range c.Indices {
			c.Indices[i].ToLower = true
		}
	}
	for i := range c.Indices {
		// Lower case name.
		c.Indices[i].Name = strings.ToLower(c.Indices[i].Name)

		icfg := c.Indices[i]
		if icfg.Type == "" {
			c.Indices[i].Type = TypeBasic
		}
		if !validTypes[c.Indices[i].Type] {
			return c, fmt.Errorf("invalid index type %q. Must be one of %v", c.Indices[i].Type, maps.Keys(validTypes))
		}
		if icfg.CardinalityThreshold < 0 || icfg.CardinalityThreshold > 100 {
			return Config{}, errors.New("cardinalityThreshold threshold must be between 0 and 100")
		}
	}

	return c, nil
}

// StringKeyword is a string search keyword.
type StringKeyword string

func (s StringKeyword) String() string {
	return string(s)
}

// FragmentKeyword represents a document fragment.
type FragmentKeyword string

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Set the index `type` to `basic` (default, keyword matching) or `fragments` (matches document heading/fragment identifiers).
  2. Omit `type` entirely to get `basic`.
  3. Check spelling — the valid values are exactly the ones listed in the error message.

Example fix

# before (hugo.toml)
[[related.indices]]
name = "fragmentrefs"
type = "fragment"
# after
[[related.indices]]
name = "fragmentrefs"
type = "fragments"
Defensive patterns

Strategy: validation

Validate before calling

# 'type' on a related index must be one of the supported values
[[related.indices]]
  name = "fragmentrefs"
  type = "fragments"  # valid: "basic", "fragments"

Type guard

func validIndexType(t string) bool {
    return t == "" || t == "basic" || t == "fragments"
}

Try / catch

if err := cfg.Validate(); err != nil {
    // error lists the allowed types — correct the config, don't suppress
    return fmt.Errorf("related index type invalid: %w", err)
}

Prevention

When it happens

Trigger: A `related.indices` entry with `type` set to an unrecognized string, e.g. `type = 'fragment'` (missing s), `type = 'keyword'`, or a typo — raised during site config decoding.

Common situations: Misspelling `fragments`; guessing type names from other search systems; upgrading configs written against docs examples with typos. `fragments` indexing (matching heading anchors) was added in Hugo 0.111, so older docs won't mention it.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/2ed63343728907ef.json. Report an issue: GitHub ↗.