{"record":{"id":"4a7f95bc0c8aebcf","repo":"gohugoio/hugo","slug":"invalid-targettype-expected-either-slice-or-map","errorCode":null,"errorMessage":"invalid targetType: expected either slice or map, received %s","messagePattern":"invalid targetType: expected either slice or map, received (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"parser/metadecoders/decoder.go","lineNumber":154,"sourceCode":"\t\treturn cast.ToFloat64E(data)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unmarshal: %T not supported\", typ)\n\t}\n}\n\n// Unmarshal will unmarshall data in format f into an interface{}.\n// This is what's needed for Hugo's /data handling.\nfunc (d Decoder) Unmarshal(data []byte, f Format) (any, error) {\n\tif len(data) == 0 {\n\t\tswitch f {\n\t\tcase CSV:\n\t\t\tswitch d.TargetType {\n\t\t\tcase \"map\":\n\t\t\t\treturn make(map[string]any), nil\n\t\t\tcase \"slice\":\n\t\t\t\treturn make([][]string, 0), nil\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"invalid targetType: expected either slice or map, received %s\", d.TargetType)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn make(map[string]any), nil\n\t\t}\n\t}\n\tvar v any\n\terr := d.UnmarshalTo(data, f, &v)\n\n\treturn v, err\n}\n\n// UnmarshalYaml unmarshals data in YAML format into v.\nfunc UnmarshalYaml(data []byte, v any) error {\n\tif err := yaml.Unmarshal(data, v); err != nil {\n\t\treturn err\n\t}\n\tif err := validateAliasLimitForCollections(v, calculateCollectionAliasLimit(len(data))); err != nil {\n\t\treturn err","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/parser/metadecoders/decoder.go#L136-L172","documentation":"Thrown by Decoder.Unmarshal (parser/metadecoders/decoder.go:154) when decoding empty data as CSV but the Decoder.TargetType is neither \"map\" nor \"slice\". With empty CSV input Hugo still needs to return the correct zero value (empty map or empty slice), and an unrecognized TargetType makes that impossible.","triggerScenarios":"Constructing a Decoder with TargetType set to something other than \"map\" or \"slice\" (e.g. \"object\", \"list\", \"\", or a typo) and then unmarshalling empty CSV data; using a custom Decoder with a bad TargetType field for CSV resources.","commonSituations":"Programmatic creation of a metadecoders.Decoder for CSV resources with a misspelled TargetType; relying on the zero value (\"\") which is invalid for CSV (Default uses \"slice\").","solutions":["Set Decoder.TargetType to exactly \"slice\" or \"map\" when handling CSV.","Use the package-level Default decoder which sets TargetType=\"slice\" unless you need map mode.","Avoid passing empty CSV data, or guard for emptiness before calling Unmarshal."],"exampleFix":"// before\ndec := metadecoders.Decoder{Format: \"csv\", TargetType: \"object\"}\nv, err := dec.Unmarshal(data, metadecoders.CSV)\n\n// after\ndec := metadecoders.Decoder{Format: \"csv\", TargetType: \"slice\"}\nv, err := dec.Unmarshal(data, metadecoders.CSV)","handlingStrategy":"validation","validationCode":"// TargetType must be map or slice for CSV.\nfunc validCSVTargetType(t string) bool {\n    return t == \"map\" || t == \"slice\"\n}","typeGuard":null,"tryCatchPattern":"if _, err := dec.Unmarshal(data, metadecoders.CSV); err != nil {\n    return fmt.Errorf(\"CSV decode config invalid: %w\", err)\n}","preventionTips":["Use metadecoders.Default or explicitly set TargetType to map/slice for CSV.","Validate TargetType before constructing a custom Decoder."],"tags":["metadecoders","csv","config","api-misuse","hugo"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}