{"record":{"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/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/related/inverted_index.go#L577-L613","documentation":"Hugo's related-content system builds an inverted index to find related pages. Each configured index may set a `cardinalityThreshold`, a percentage (0-100) that filters out overly common keywords (e.g. 50 drops keywords used in >50% of documents). `DecodeConfig` in related/inverted_index.go rejects any index whose threshold is negative or above 100, because a percentage outside that range is meaningless.","triggerScenarios":"Setting `cardinalityThreshold` to a value < 0 or > 100 under any `[related.indices]` entry in hugo.toml/yaml/json. Triggered during site build when the related config is decoded (inverted_index.go:594).","commonSituations":"Confusing `cardinalityThreshold` (a 0-100 percentage) with `weight` (uncapped integer); copy-pasting a tutorial value out of range; migrating from older Hugo related config; typo such as a stray minus sign or extra digit.","solutions":["Set cardinalityThreshold to an integer between 0 and 100 inclusive in the offending [related.indices] entry.","If unsure what value to use, omit the field entirely so it defaults to 0 (no keyword filtering).","Audit every [related.indices] block, not just the first — the loop validates each one."],"exampleFix":"# before\n[related.indices]\nname = \"tags\"\nweight = 100\ncardinalityThreshold = 150\n\n# after\n[related.indices]\nname = \"tags\"\nweight = 100\ncardinalityThreshold = 50","handlingStrategy":"validation","validationCode":"// Validate each related index before relying on DecodeConfig\nfor _, idx := range cfg.Indices {\n    if idx.CardinalityThreshold < 0 || idx.CardinalityThreshold > 100 {\n        return fmt.Errorf(\"index %q: cardinalityThreshold must be 0-100, got %d\", idx.Name, idx.CardinalityThreshold)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat cardinalityThreshold as a percentage (0-100), not a weight.","Omit it to accept the safe default of 0.","Lint the [related] config block in CI."],"tags":["hugo","configuration","related-content","validation"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}