gohugoio/hugo · error
type %T not supported
Error message
type %T not supported
What it means
`transform.Unmarshal` received a value that is neither an UnmarshableResource nor convertible to a string (via `types.ToStringE`). The function only accepts Resource objects or raw string data; passing maps, slices, Pages, or already-decoded data lands here, with the Go type printed via %T.
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 8a468df065)
Solutions
- Pass raw string content or a Resource: e.g. `transform.Unmarshal ($file.Content)` or `transform.Unmarshal $resource`.
- Remove redundant unmarshal calls — data from `site.Data` or a prior `unmarshal` is already decoded.
- When using options, check argument order: `transform.Unmarshal OPTIONS DATA` (options map first).
Example fix
{{/* before */}}
{{ $d := site.Data.config | transform.Unmarshal }}
{{/* after */}}
{{ $d := site.Data.config }}{{/* already decoded */}} Defensive patterns
Strategy: type-guard
Type guard
{{/* Unmarshal accepts only strings, []byte, or Resources */}}
{{ if or (reflect.IsMap . | not) (eq (printf "%T" .) "string") }}...{{ end }}
{{/* simplest: coerce first */}}
{{ $data := transform.Unmarshal (string $input) }} Try / catch
{{ with try (transform.Unmarshal $input) }}
{{ with .Err }}{{ errorf "cannot unmarshal %T: %s" $input . }}{{ else }}{{ $data := .Value }}{{ end }}
{{ end }} Prevention
- Pass only a string, []byte, or a Resource to transform.Unmarshal — never a map/slice that is already unmarshaled
- Coerce values with (string $x) before unmarshaling when the source type is uncertain
- Don't double-unmarshal: .Data from resources.GetRemote JSON handling or site data files may already be structured
When it happens
Trigger: Calling `transform.Unmarshal` with a non-string, non-Resource argument — e.g. a map/slice, a Page object, nil-ish complex values, or piping already-unmarshaled data through `unmarshal` a second time.
Common situations: Double-unmarshaling (`.Content | unmarshal | unmarshal`), passing `.Params` or a data object from `site.Data` (already decoded) instead of raw text, or getting arguments in the wrong order in a dict-options call so the options map is treated as data.
Related errors
- first argument must be a map
- arguments to symdiff must be slices or arrays
- can't iterate over %T
- text must be a string
- unmarshal takes 1 or 2 arguments
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/44b2b70b0be72bb3.json.
Report an issue: GitHub ↗.