{"id":"da111fb8c783e624","repo":"gohugoio/hugo","slug":"failed-to-decode-related-config-w","errorCode":null,"errorMessage":"failed to decode related config: %w","messagePattern":"failed to decode related config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/allconfig/alldecoders.go","lineNumber":360,"sourceCode":"\t\t\t\tfor k, v := range m {\n\t\t\t\t\tif k == \"\" || v == \"\" {\n\t\t\t\t\t\tdelete(m, k)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.c.Taxonomies = m\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t},\n\t\"related\": {\n\t\tkey:    \"related\",\n\t\tweight: 100, // This needs to be decoded after taxonomies.\n\t\tdecode: func(d decodeWeight, p decodeConfig) error {\n\t\t\tif p.p.IsSet(d.key) {\n\t\t\t\tvar err error\n\t\t\t\tp.c.Related, err = related.DecodeConfig(p.p.GetParams(d.key))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to decode related config: %w\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tp.c.Related = related.DefaultConfig\n\t\t\t\tif _, found := p.c.Taxonomies[\"tag\"]; found {\n\t\t\t\t\tp.c.Related.Add(related.IndexConfig{Name: \"tags\", Weight: 80, Type: related.TypeBasic})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t},\n\n\t\"cascade\": {\n\t\tkey: \"cascade\",\n\t\tdecode: func(d decodeWeight, p decodeConfig) error {\n\t\t\tvar err error\n\t\t\tp.c.Cascade, err = page.DecodeCascadeConfig(p.p.Get(d.key))\n\t\t\treturn err\n\t\t},","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/config/allconfig/alldecoders.go#L342-L378","documentation":"Emitted when the [related] config section is set but related.DecodeConfig cannot decode it into Hugo's related-content configuration (index definitions, thresholds, etc.). Hugo only decodes this section when explicitly present (otherwise it falls back to related.DefaultConfig), so this error always points at a user-authored [related] block.","triggerScenarios":"A [related] section whose shape related.DecodeConfig rejects: 'indices' not being a list of maps, an index entry missing 'name', invalid 'type' values, non-numeric threshold/weight values, or wrong nesting such as putting index fields directly under [related] instead of [[related.indices]].","commonSituations":"Copying a related-content snippet between YAML and TOML and losing the array-of-tables structure ([[related.indices]] in TOML vs a YAML list); setting threshold or weight as strings; using fields from newer Hugo versions (e.g. type = 'fragments' options, cardinalityThreshold) on an older Hugo.","solutions":["Structure indices as an array of tables: [[related.indices]] entries each with name/weight, not fields directly under [related].","Make threshold, weight and toLower the correct types (numbers/booleans, not strings).","Compare your block against the current docs at gohugo.io/content-management/related/ for your Hugo version.","Delete the [related] section entirely to fall back to Hugo's sensible defaults if you don't need customization."],"exampleFix":"# before\n[related]\nname = 'keywords'\nweight = '100'\n# after\n[related]\nthreshold = 80\n[[related.indices]]\nname = 'keywords'\nweight = 100","handlingStrategy":"validation","validationCode":"// related config must decode into related.Config: check shape first\nrel, ok := cfg.Get(\"related\").(map[string]any)\nif ok {\n    if idx, ok := rel[\"indices\"]; ok {\n        if _, ok := idx.([]any); !ok {\n            return errors.New(\"related.indices must be an array of tables\")\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"conf, err := allconfig.LoadConfig(opts)\nif err != nil && strings.Contains(err.Error(), \"related config\") {\n    // point the user at the [related] section specifically\n    return err\n}","preventionTips":["Model your [related] block on the documented default (threshold, includeNewer, toLower, [[related.indices]])","indices must be an array of tables ([[related.indices]] in TOML), each with name and weight","When overriding related config you replace the default entirely — supply the full structure, not a partial patch","Keep weight/threshold numeric; strings there break mapstructure decoding"],"tags":["hugo","config","related-content"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}