gohugoio/hugo · error
invalid targetType: expected either slice or map, received %
Error message
invalid targetType: expected either slice or map, received %s
What it means
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.
Source
Thrown at parser/metadecoders/decoder.go:154
return cast.ToFloat64E(data)
default:
return nil, fmt.Errorf("unmarshal: %T not supported", typ)
}
}
// Unmarshal will unmarshall data in format f into an interface{}.
// This is what's needed for Hugo's /data handling.
func (d Decoder) Unmarshal(data []byte, f Format) (any, error) {
if len(data) == 0 {
switch f {
case CSV:
switch d.TargetType {
case "map":
return make(map[string]any), nil
case "slice":
return make([][]string, 0), nil
default:
return nil, fmt.Errorf("invalid targetType: expected either slice or map, received %s", d.TargetType)
}
default:
return make(map[string]any), nil
}
}
var v any
err := d.UnmarshalTo(data, f, &v)
return v, err
}
// UnmarshalYaml unmarshals data in YAML format into v.
func UnmarshalYaml(data []byte, v any) error {
if err := yaml.Unmarshal(data, v); err != nil {
return err
}
if err := validateAliasLimitForCollections(v, calculateCollectionAliasLimit(len(data))); err != nil {
return errView on GitHub (pinned to 52c9bd7908)
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.
Example fix
// before
dec := metadecoders.Decoder{Format: "csv", TargetType: "object"}
v, err := dec.Unmarshal(data, metadecoders.CSV)
// after
dec := metadecoders.Decoder{Format: "csv", TargetType: "slice"}
v, err := dec.Unmarshal(data, metadecoders.CSV) Defensive patterns
Strategy: validation
Validate before calling
// TargetType must be map or slice for CSV.
func validCSVTargetType(t string) bool {
return t == "map" || t == "slice"
} Try / catch
if _, err := dec.Unmarshal(data, metadecoders.CSV); err != nil {
return fmt.Errorf("CSV decode config invalid: %w", err)
} Prevention
- Use metadecoders.Default or explicitly set TargetType to map/slice for CSV.
- Validate TargetType before constructing a custom Decoder.
When it happens
Trigger: 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.
Common situations: 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").
Related errors
- cannot unmarshal CSV into %T: invalid targetType: expected e
- cannot unmarshal CSV into %T
- %q is not a valid configuration format
- unmarshal: %T not supported
- unmarshal of format %q is not supported
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/4a7f95bc0c8aebcf.
Report an issue: GitHub.