{"id":"53687f450e69b5ee","repo":"gohugoio/hugo","slug":"no-related-config-provided","errorCode":null,"errorMessage":"no related config provided","messagePattern":"no related config provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"related/inverted_index.go","lineNumber":561,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\n\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 {","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/related/inverted_index.go#L543-L579","documentation":"`related.DecodeConfig` (related/inverted_index.go:559) refuses a nil params map. It distinguishes \"no config passed at all\" (nil) from \"empty config\" — a nil map means the caller invoked config decoding without any `related` section value, which is a programming/config-plumbing error rather than a user choosing empty settings.","triggerScenarios":"Calling related.DecodeConfig(nil) — in Hugo this happens if the config loader passes a nil Params for the `related` key instead of omitting the decode entirely.","commonSituations":"Custom Hugo forks/tools invoking DecodeConfig directly with nil; a `related:` key present in config but with a null value (e.g. `related:` alone on a line in YAML yields nil).","solutions":["Remove the bare `related:` key from the site config, or give it actual content (indices, threshold).","In code, only call DecodeConfig when a non-nil related config map exists; otherwise use related.DefaultConfig."],"exampleFix":"# before (hugo.yaml)\nrelated:\n# after\nrelated:\n  threshold: 80\n  indices:\n    - name: keywords\n      weight: 100","handlingStrategy":"validation","validationCode":"cfg := related.DecodeConfig(p) // or use related.DefaultConfig\nif cfg == nil {\n    cfg = &related.DefaultConfig\n}","typeGuard":"func hasRelatedConfig(cfg *related.Config) bool { return cfg != nil }","tryCatchPattern":"idx, err := related.NewInvertedIndex(cfg)\nif err != nil {\n    return fmt.Errorf(\"related config missing — set [related] in site config or use defaults: %w\", err)\n}","preventionTips":["Never pass a nil config when constructing a related-content index; fall back to related.DefaultConfig explicitly","If you override `related` in site config, ensure the table is actually populated, not just declared"],"tags":["related-content","config","hugo"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}