{"id":"78ece3fafb916381","repo":"gohugoio/hugo","slug":"cardinalitythreshold-threshold-must-be-between-0-a","errorCode":null,"errorMessage":"cardinalityThreshold threshold must be between 0 and 100","messagePattern":"cardinalityThreshold threshold must be between 0 and 100","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"related/inverted_index.go","lineNumber":595,"sourceCode":"\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\n\nfunc (f FragmentKeyword) String() string {\n\treturn string(f)","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/related/inverted_index.go#L577-L613","documentation":"Hugo's related-content engine (used by .Site.RegularPages.Related and the `related` site config) validates each configured index at config decode time. `cardinalityThreshold` is expressed as a percentage of documents a keyword may appear in before it is treated as too common and dropped from the inverted index, so any value outside 0–100 is rejected and site config loading fails.","triggerScenarios":"Setting `related.indices[].cardinalityThreshold` in hugo.toml/hugo.yaml to a negative number or a value above 100. The check runs in DecodeConfig in related/inverted_index.go when Hugo loads site configuration, i.e. on any `hugo` or `hugo server` invocation.","commonSituations":"Developers assume the threshold is an absolute document count (e.g. 500) rather than a percentage; typos like -1 intended to mean 'disabled'; copy-pasting related-content config from blog posts that used fictional values.","solutions":["Set cardinalityThreshold to a value between 0 and 100 in the related indices config (0 disables the pruning).","If you wanted to prune very common keywords, use a percentage like 80–90 rather than a document count.","Remove the key entirely to accept the default of 0."],"exampleFix":"# before (hugo.toml)\n[related]\n  [[related.indices]]\n    name = \"tags\"\n    cardinalityThreshold = 500\n\n# after\n[related]\n  [[related.indices]]\n    name = \"tags\"\n    cardinalityThreshold = 80","handlingStrategy":"validation","validationCode":"if cfg.CardinalityThreshold < 0 || cfg.CardinalityThreshold > 100 {\n    return fmt.Errorf(\"cardinalityThreshold must be 0-100, got %d\", cfg.CardinalityThreshold)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate related-config values at site-config load time, not at query time","Treat the threshold as a percentage and clamp/reject out-of-range values in your own config schema","Add a config test that builds the site with your related settings to catch bad values in CI"],"tags":["hugo","config","related-content","validation"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}