gohugoio/hugo · error

failed to decode options: %w

Error message

failed to decode options: %w

What it means

After validating that the first argument is a map, `transform.Unmarshal` decodes it into its decoder options struct (delimiter, comment, format, etc.) via mapstructure. If a key's value can't be converted to the expected type — for example a delimiter that isn't a single character, or a value of the wrong kind — the underlying decode error is wrapped and returned as this error.

Source

Thrown at tpl/transform/unmarshal.go:59

	}

	var data any
	decoder := metadecoders.Default

	if len(args) == 1 {
		data = args[0]
	} else {
		m, ok := args[0].(map[string]any)
		if !ok {
			return nil, errors.New("first argument must be a map")
		}

		var err error

		data = args[1]
		decoder, err = decodeDecoder(m)
		if err != nil {
			return nil, fmt.Errorf("failed to decode options: %w", err)
		}
	}

	if r, ok := data.(resource.UnmarshableResource); ok {
		key := r.Key()

		if key == "" {
			return nil, errors.New("no Key set in Resource")
		}

		if decoder != metadecoders.Default {
			key += decoder.OptionsKey()
		}

		v, err := ns.cacheUnmarshal.GetOrCreate(key, func(string) (*resources.StaleValue[any], error) {
			var f metadecoders.Format
			if decoder.Format != "" {
				f = metadecoders.FormatFromString(decoder.Format)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Read the wrapped error text after the prefix — it names the failing option and why.
  2. Ensure `delimiter` and `comment` are single characters, e.g. `(dict "delimiter" ";")`.
  3. Check each option value's type against the docs for transform.Unmarshal (strings for format, single chars for CSV controls, bool for lazyQuotes).

Example fix

<!-- before -->
{{ transform.Unmarshal (dict "delimiter" "||") $csv }}
<!-- after -->
{{ transform.Unmarshal (dict "delimiter" "|") $csv }}
Defensive patterns

Strategy: validation

Validate before calling

{{/* use only documented option keys, e.g. for CSV: */}}
{{ $opts := dict "delimiter" ";" "comment" "#" "lazyQuotes" true }}
{{ $d := unmarshal $opts $csv }}

Prevention

When it happens

Trigger: `{{ transform.Unmarshal (dict "delimiter" ";;") $csv }}` — CSV delimiter/comment must decode to a single rune; passing a slice or map where a scalar option is expected; option values of incompatible types that mapstructure cannot weakly convert.

Common situations: CSV parsing with a multi-character delimiter string; options loaded from site config or front matter with wrong types; typos in values (keys that are unknown are generally ignored — this error is about values that fail to convert).

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/ba4443a32b418857.json. Report an issue: GitHub ↗.