{"id":"8b1a2245fa0dc82c","repo":"gohugoio/hugo","slug":"empty-related-config-provided","errorCode":null,"errorMessage":"empty related config provided","messagePattern":"empty related config provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"related/inverted_index.go","lineNumber":565,"sourceCode":"\treturn result, nil\n}\n\n// normalizes num to a number between 0 and 100.\nfunc norm(num, min, max int) int {\n\tif min > max {\n\t\tpanic(\"min > max\")\n\t}\n\treturn int(math.Floor((float64(num-min) / float64(max-min) * 100) + 0.5))\n}\n\n// DecodeConfig decodes a slice of map into Config.\nfunc DecodeConfig(m hmaps.Params) (Config, error) {\n\tif m == nil {\n\t\treturn Config{}, errors.New(\"no related config provided\")\n\t}\n\n\tif len(m) == 0 {\n\t\treturn Config{}, errors.New(\"empty related config provided\")\n\t}\n\n\tvar c Config\n\n\tif err := mapstructure.WeakDecode(m, &c); err != nil {\n\t\treturn c, err\n\t}\n\n\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 {","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/related/inverted_index.go#L547-L583","documentation":"Companion check to error 506: `DecodeConfig` also rejects a non-nil but zero-length params map (related/inverted_index.go:564). An empty `related = {}` block would silently disable related content with no indices, so Hugo fails fast to force either a real configuration or removal of the section (defaults apply when the section is absent).","triggerScenarios":"Calling related.DecodeConfig with an empty hmaps.Params — a `[related]` / `related: {}` section in site config that contains no keys.","commonSituations":"Adding an empty `[related]` table in hugo.toml as a placeholder; commenting out all keys inside the section but leaving the header; templating/merging config that produces `related: {}`.","solutions":["Delete the empty `related` section so Hugo uses its default related config (keywords + date indices).","Or fill the section with at least the settings you want, e.g. `threshold` and one `indices` entry."],"exampleFix":"# before (hugo.toml)\n[related]\n# after\n[related]\nthreshold = 80\n[[related.indices]]\nname = \"keywords\"\nweight = 100","handlingStrategy":"validation","validationCode":"# An empty [related] table removes the defaults — declare at least one index\n[related]\n  threshold = 80\n  [[related.indices]]\n    name = \"keywords\"\n    weight = 100","typeGuard":"func configPopulated(cfg related.Config) bool { return len(cfg.Indices) > 0 }","tryCatchPattern":"if err := validate(cfg); err != nil {\n    return fmt.Errorf(\"[related] declared but has no indices — remove the table to use defaults, or add indices: %w\", err)\n}","preventionTips":["Overriding `related` in config replaces the defaults entirely — always include at least one `[[related.indices]]` entry","If you only want to tweak the threshold, still restate the indices you need"],"tags":["related-content","config","hugo"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}