gohugoio/hugo · error

failed to decode options: %w

Error message

failed to decode options: %w

What it means

transform.Unmarshal accepts an optional first-argument options map (e.g. {{ transform.Unmarshal (dict "delimiter" ";") $data }}). decodeDecoder (unmarshal.go:167-198) processes this map — handling Delimiter/Comment as runes and WeakDecode-ing the rest into metadecoders.Decoder options. If any of that fails, the error wraps the decode failure (unmarshal.go:57-60).

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 52c9bd7908)

Solutions

  1. Ensure Delimiter and Comment are single-character strings.
  2. Remove unsupported/unknown keys from the options map.
  3. Check the wrapped error for the specific field that failed.

Example fix

// before — multi-char delimiter rejected
{{ transform.Unmarshal (dict "delimiter" ",,") $csvResource }}

// after — single-char delimiter
{{ transform.Unmarshal (dict "delimiter" ",") $csvResource }}
Defensive patterns

Strategy: validation

Validate before calling

// Validate option keys/types before passing to transform.Unmarshal:
//   - Delimiter and Comment must be single characters
//   - Only known keys: delimiter, comment, format (and decoder-specific ones)
{{ transform.Unmarshal (dict "delimiter" ",") $csv }}

Prevention

When it happens

Trigger: Passing an options map to transform.Unmarshal with an invalid value — e.g. a multi-character string for Delimiter/Comment (stringToRune rejects >1 char at unmarshal.go:216), or a value WeakDecode cannot coerce into the Decoder struct.

Common situations: Setting Delimiter to ",," instead of "," for CSV; passing an unknown option type; typos in option keys that mapstructure then mishandles; copying CSV examples with wrong delimiter values.

Understand the failure class

Related errors


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