{"id":"2ed63343728907ef","repo":"gohugoio/hugo","slug":"invalid-index-type-q-must-be-one-of-v","errorCode":null,"errorMessage":"invalid index type %q. Must be one of %v","messagePattern":"invalid index type %q\\. Must be one of (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"related/inverted_index.go","lineNumber":592,"sourceCode":"\tif c.Threshold < 0 || c.Threshold > 100 {\n\t\treturn Config{}, errors.New(\"related threshold must be between 0 and 100\")\n\t}\n\n\tif c.ToLower {\n\t\tfor i := range c.Indices {\n\t\t\tc.Indices[i].ToLower = true\n\t\t}\n\t}\n\tfor i := range c.Indices {\n\t\t// Lower case name.\n\t\tc.Indices[i].Name = strings.ToLower(c.Indices[i].Name)\n\n\t\ticfg := c.Indices[i]\n\t\tif icfg.Type == \"\" {\n\t\t\tc.Indices[i].Type = TypeBasic\n\t\t}\n\t\tif !validTypes[c.Indices[i].Type] {\n\t\t\treturn c, fmt.Errorf(\"invalid index type %q. Must be one of %v\", c.Indices[i].Type, maps.Keys(validTypes))\n\t\t}\n\t\tif icfg.CardinalityThreshold < 0 || icfg.CardinalityThreshold > 100 {\n\t\t\treturn Config{}, errors.New(\"cardinalityThreshold threshold must be between 0 and 100\")\n\t\t}\n\t}\n\n\treturn c, nil\n}\n\n// StringKeyword is a string search keyword.\ntype StringKeyword string\n\nfunc (s StringKeyword) String() string {\n\treturn string(s)\n}\n\n// FragmentKeyword represents a document fragment.\ntype FragmentKeyword string","sourceCodeStart":574,"sourceCodeEnd":610,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/related/inverted_index.go#L574-L610","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set the index `type` to `basic` (default, keyword matching) or `fragments` (matches document heading/fragment identifiers).","Omit `type` entirely to get `basic`.","Check spelling — the valid values are exactly the ones listed in the error message."],"exampleFix":"# before (hugo.toml)\n[[related.indices]]\nname = \"fragmentrefs\"\ntype = \"fragment\"\n# after\n[[related.indices]]\nname = \"fragmentrefs\"\ntype = \"fragments\"","handlingStrategy":"validation","validationCode":"# 'type' on a related index must be one of the supported values\n[[related.indices]]\n  name = \"fragmentrefs\"\n  type = \"fragments\"  # valid: \"basic\", \"fragments\"","typeGuard":"func validIndexType(t string) bool {\n    return t == \"\" || t == \"basic\" || t == \"fragments\"\n}","tryCatchPattern":"if err := cfg.Validate(); err != nil {\n    // error lists the allowed types — correct the config, don't suppress\n    return fmt.Errorf(\"related index type invalid: %w\", err)\n}","preventionTips":["Only set `type = \"basic\"` or `type = \"fragments\"` on a related index; omit the key for the default","Check the Hugo docs for your version before using newer index types — valid values are version-dependent","Let the error message's list of allowed values (%v) guide the fix instead of guessing"],"tags":["related-content","config","validation","hugo"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}