{"record":{"id":"ea5c0bbe4640e033","repo":"gohugoio/hugo","slug":"failed-convert-config-to-map-s","errorCode":null,"errorMessage":"failed convert config to map: %s","messagePattern":"failed convert config to map: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"output/config.go","lineNumber":47,"sourceCode":"type OutputFormatConfig struct {\n\t// The MediaType string. This must be a configured media type.\n\tMediaType string\n\tFormat\n}\n\nvar defaultOutputFormat = Format{\n\tBaseName: \"index\",\n\tRel:      \"alternate\",\n}\n\nfunc DecodeConfig(mediaTypes media.Types, in any) (*config.ConfigNamespace[map[string]OutputFormatConfig, Formats], error) {\n\tbuildConfig := func(in any) (Formats, any, error) {\n\t\tf := make(Formats, len(DefaultFormats))\n\t\tcopy(f, DefaultFormats)\n\t\tif in != nil {\n\t\t\tm, err := hmaps.ToStringMapE(in)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"failed convert config to map: %s\", err)\n\t\t\t}\n\t\t\tm = hmaps.CleanConfigStringMap(m)\n\n\t\t\tfor k, v := range m {\n\t\t\t\tfound := false\n\t\t\t\tfor i, vv := range f {\n\t\t\t\t\t// Both are lower case.\n\t\t\t\t\tif k == vv.Name {\n\t\t\t\t\t\t// Merge it with the existing\n\t\t\t\t\t\tif err := decode(mediaTypes, v, &f[i]); err != nil {\n\t\t\t\t\t\t\treturn f, nil, err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif found {\n\t\t\t\t\tcontinue\n\t\t\t\t}","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/output/config.go#L29-L65","documentation":"Thrown by output.DecodeConfig (output/config.go:47) when hmaps.ToStringMapE(in) fails to convert the 'outputFormats' configuration value into a map[string]any. The %s inserts the cast error. Hugo expects the [outputFormats] section to be a map keyed by format name; this error means the top-level value is an array, a scalar, or otherwise not a map.","triggerScenarios":"Defining [outputFormats] as an array (outputFormats = [{name=\"x\"}]) or a scalar in hugo.toml; loading a config via a source that yields a slice instead of a map; a config merge/overlay producing a non-map at that key.","commonSituations":"Migrating from an older Hugo config syntax that used a different shape; typos in TOML that create an array-of-tables instead of a table; YAML config using a list where a mapping is expected; environment-injected config overrides that replace the map with a scalar.","solutions":["Ensure [outputFormats] in hugo.toml is a table/map: [outputFormats.NAME] with each format as a sub-table, not an inline array.","In YAML config use outputFormats: { NAME: {...} } rather than outputFormats: [{...}].","Run hugo config to dump the resolved config and confirm outputFormats is a map.","Check any --config overrides or theme config mounts for a conflicting non-map definition."],"exampleFix":"# before (array instead of map)\noutputFormats = [\n  { name = \"MYFORMAT\", mediaType = \"text/html\" }\n]\n\n# after (map keyed by name)\n[outputFormats.MYFORMAT]\nmediaType = \"text/html\"\nbaseName = \"index\"","handlingStrategy":"validation","validationCode":"// Ensure the outputFormats config value is a map before DecodeConfig.\nfunc ensureOutputFormatsMap(in any) error {\n    if in == nil { return nil }\n    if _, ok := in.(map[string]any); !ok {\n        return fmt.Errorf(\"outputFormats must be a map, got %T\", in)\n    }\n    return nil\n}","typeGuard":"func isConfigMap(in any) bool {\n    _, ok := in.(map[string]any)\n    return ok || in == nil\n}","tryCatchPattern":"ns, err := output.DecodeConfig(mediaTypes, raw)\nif err != nil {\n    return fmt.Errorf(\"invalid outputFormats config: %w\", err)\n}","preventionTips":["Author [outputFormats] as TOML tables or YAML mappings, never arrays.","Run `hugo config` after config edits to catch structural errors.","Review theme/config overlays for conflicting shapes."],"tags":["config","output-formats","hugo"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}