gohugoio/hugo · error
format %q not supported
Error message
format %q not supported
What it means
When unmarshaling a Resource with an explicit `format` option, Hugo maps the string through `metadecoders.FormatFromString`. If the string doesn't correspond to a known decodable format (json, toml, yaml/yml, csv, xml), the lookup returns empty and this error is raised inside the cached unmarshal path.
Source
Thrown at tpl/transform/unmarshal.go:79
}
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)
if f == "" {
return nil, fmt.Errorf("format %q not supported", decoder.Format)
}
} else {
f = metadecoders.FormatFromStrings(r.MediaType().Suffixes()...)
if f == "" {
return nil, fmt.Errorf("MIME %q not supported", r.MediaType())
}
}
reader, err := r.ReadSeekCloser()
if err != nil {
return nil, err
}
defer reader.Close()
b, err := io.ReadAll(reader)
if err != nil {
return nil, err
}View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Use a supported format string: json, toml, yaml, yml, csv, or xml.
- Fix typos — the value is matched exactly (lowercase).
- If the resource already has a recognized media type/extension, omit the format option and let Hugo infer it; for genuinely unsupported formats, fetch the content and parse it another way.
Example fix
<!-- before -->
{{ transform.Unmarshal (dict "format" "ymal") $r }}
<!-- after -->
{{ transform.Unmarshal (dict "format" "yaml") $r }} Defensive patterns
Strategy: validation
Validate before calling
{{ $ext := path.Ext $file | strings.TrimPrefix "." }}
{{ if in (slice "json" "yaml" "yml" "toml" "csv" "xml") $ext }}{{ $d := unmarshal $content }}{{ else }}{{ errorf "cannot unmarshal %q" $file }}{{ end }} Prevention
- Only unmarshal JSON, YAML, TOML, CSV, or XML content
- For remote resources, ensure the media type/extension is recognized; use resources.GetRemote with a proper URL suffix or set the format via options
- Bare strings are format-sniffed — make sure content actually starts like valid JSON/TOML/YAML
When it happens
Trigger: `{{ transform.Unmarshal (dict "format" "txt") $resource }}` or any format string that isn't one of Hugo's metadecoder formats; typos like "jsn" or "ymal"; forcing a format on a resource whose content type has no decoder.
Common situations: Trying to unmarshal plain-text or custom-format remote resources by inventing a format name; typoed format strings in shared partials; expecting formats Hugo doesn't decode (ini, properties, hcl).
Related errors
- unmarshal takes 1 or 2 arguments
- first argument must be a map
- failed to decode options: %w
- MIME %q not supported
- type %T not supported
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/c05d9e813b42c25a.json.
Report an issue: GitHub ↗.