gohugoio/hugo · error

type %T not supported

Error message

type %T not supported

What it means

Thrown by transform.Unmarshal (tpl/transform/unmarshal.go:121) in the non-Resource code path after types.ToStringE(data) fails. Unmarshal only accepts data that is a string, []byte, json.RawMessage, or an UnmarshableResource; any other Go type reaches this branch. The %T prints the offending concrete type so the developer can see exactly what was passed.

Source

Thrown at tpl/transform/unmarshal.go:121

			return &resources.StaleValue[any]{
				Value: v,
				StaleVersionFunc: func() uint32 {
					return resource.StaleVersion(r)
				},
			}, nil
		})
		if err != nil {
			return nil, err
		}

		return v.Value, nil

	}

	dataStr, err := types.ToStringE(data)
	if err != nil {
		return nil, fmt.Errorf("type %T not supported", data)
	}

	if strings.TrimSpace(dataStr) == "" {
		return nil, nil
	}

	key := hashing.XxHashFromStringHexEncoded(dataStr)

	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)
			if f == "" {
				return nil, fmt.Errorf("format %q not supported", decoder.Format)

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Coerce the value to a string before unmarshaling: {{ transform.Unmarshal (string $value) }}
  2. Pass a Resource obtained via resources.Get / .Resources instead of a raw value
  3. If the value is already a map/slice, use it directly instead of re-unmarshaling
  4. In Go, assert resource.UnmarshableResource or string/[]byte before calling ns.Unmarshal

Example fix

// before
{{ transform.Unmarshal $param }}
// after
{{ transform.Unmarshal (string $param) }}
Defensive patterns

Strategy: validation

Validate before calling

// In Go: check the data type before calling Unmarshal.
switch v := data.(type) {
case string, []byte, json.RawMessage:
    // safe
resource.UnmarshableResource:
    // safe
default:
    s, err := types.ToStringE(v)
    if err != nil {
        return fmt.Errorf("convert data to string before Unmarshal: %w", err)
    }
    data = s
}
// In templates: {{ transform.Unmarshal (string $value) }}

Prevention

When it happens

Trigger: Calling {{ transform.Unmarshal $value }} (or the Go Namespace.Unmarshal) where $value is an int, bool, struct, map, or slice that is neither string-convertible nor a resource.UnmarshableResource. Common: piping a .Param that resolves to a number or array, or an .Scratch value holding a non-string type.

Common situations: Passing already-decoded data (a map from a data file) back into Unmarshal; piping a resource object that does not implement UnmarshableResource; passing front-matter values of unknown type straight from .Params.

Related errors


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