gohugoio/hugo · error
invalid index type . Must be one of
Error message
invalid index type %q. Must be one of %v
What it means
Returned by related.DecodeConfig when an IndexConfig.Type is neither "basic" nor "fragments" (the only entries in validTypes). After defaulting an empty Type to "basic", any remaining unrecognised value is rejected. The error lists the valid type keys so the developer knows the accepted set.
Solutions
- Set the index type to "basic" (default for keyword/date indices) or "fragments" (for heading-fragment matching).
- Omit the type field entirely -- DecodeConfig defaults empty to "basic".
- Check the error message: it prints the accepted map keys.
Example fix
// before [[related.indices]] name = "tags" type = "fragment" weight = 100 // after type = "fragments"
Defensive patterns
Strategy: validation
Validate before calling
var validRelatedTypes = map[string]bool{"basic": true, "fragments": true}
func validateIndexTypes(cfg related.Config) error {
for _, i := range cfg.Indices {
t := i.Type
if t == "" { t = "basic" }
if !validRelatedTypes[t] {
return fmt.Errorf("index %q has invalid type %q", i.Name, i.Type)
}
}
return nil
} Type guard
func isValidRelatedType(t string) bool {
t = strings.ToLower(strings.TrimSpace(t))
if t == "" { t = "basic" }
return t == "basic" || t == "fragments"
} Prevention
- Use only "basic" or "fragments" for index types.
- Omit type to default to "basic".
- Validate config in CI with a lint step before building.
When it happens
Trigger: Setting [[related.indices]] type = "fulltext" (or any string other than basic/fragments) in hugo.toml. DecodeConfig runs at site config load, so this fails during Hugo startup before any build.
Common situations: Typing the index type (e.g. "fragment" singular, "semantic", "text"); assuming a type exists that this Hugo version does not support; copying config from a newer/older Hugo with different supported types.
Related errors
- empty related config provided
- failed to decode related config
- no related config provided
- related threshold must be between 0 and 100
- config needs a filename
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/2ed63343728907ef.
Report an issue: GitHub.
Appendix: 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 stringView on GitHub (pinned to 52c9bd7908)