gohugoio/hugo · error

cannot unmarshal CSV into %T: invalid targetType: expected e

Error message

cannot unmarshal CSV into %T: invalid targetType: expected either slice or map, received %s

What it means

Thrown by Decoder.unmarshalCSV (parser/metadecoders/decoder.go:374) when decoding non-empty CSV into a *any target but Decoder.TargetType is neither "map" nor "slice". This mirrors the empty-data check (error 509) but fires for the populated-CSV path. The %s names the invalid TargetType.

Source

Thrown at parser/metadecoders/decoder.go:374

				if seen[fieldName] {
					return fmt.Errorf("cannot unmarshal CSV into %T: header row contains duplicate field names", v)
				}
				seen[fieldName] = true
			}

			sm := make([]map[string]string, len(records)-1)
			for i, record := range records[1:] {
				m := make(map[string]string, len(records[0]))
				for j, col := range record {
					m[records[0][j]] = col
				}
				sm[i] = m
			}
			*vv = sm
		case "slice":
			*vv = records
		default:
			return fmt.Errorf("cannot unmarshal CSV into %T: invalid targetType: expected either slice or map, received %s", v, d.TargetType)
		}
	default:
		return fmt.Errorf("cannot unmarshal CSV into %T", v)
	}

	return nil
}

func parseORGDate(s string) string {
	r := regexp.MustCompile(`[<\[](\d{4}-\d{2}-\d{2}) .*[>\]]`)
	if m := r.FindStringSubmatch(s); m != nil {
		return m[1]
	}
	return s
}

func (d Decoder) unmarshalORG(data []byte, v any) error {
	config := org.New()

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Set Decoder.TargetType to exactly "slice" or "map" for CSV decoding.
  2. Use metadecoders.Default (TargetType="slice") unless map mode is required.
  3. Validate TargetType against {"slice","map"} before invoking the decoder.

Example fix

// before
dec := metadecoders.Decoder{Delimiter: ',', TargetType: "rows"}

// after
dec := metadecoders.Default   // or TargetType: "slice"
Defensive patterns

Strategy: validation

Validate before calling

func validCSVTargetType(t string) bool {
    return t == "map" || t == "slice"
}

Try / catch

if err := dec.UnmarshalTo(data, metadecoders.CSV, &v); err != nil {
    return fmt.Errorf("invalid CSV TargetType: %w", err)
}

Prevention

When it happens

Trigger: Constructing a Decoder with a misspelled/unsupported TargetType (e.g. "object", "", "dict") and decoding CSV data into *interface{}; using a custom Decoder instead of Default without setting TargetType correctly.

Common situations: Programmatic creation of a CSV decoder with a bad TargetType; relying on zero-value TargetType ("") instead of Default; a config field that feeds TargetType with an unexpected value.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/ca1c60de617e7aee. Report an issue: GitHub.