gohugoio/hugo · error
unknown format
Error message
unknown format
What it means
When `transform.Unmarshal` is given a raw string and no explicit `format` option, Hugo sniffs the content with `decoder.FormatFromContentString` (looking for JSON braces, TOML/YAML markers, etc.). If the sniffer can't classify the string, this generic 'unknown format' error is returned.
Source
Thrown at tpl/transform/unmarshal.go:144
}
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)
}
} else {
f = decoder.FormatFromContentString(dataStr)
if f == "" {
return nil, errors.New("unknown format")
}
}
v, err := decoder.Unmarshal([]byte(dataStr), f)
if err != nil {
return nil, err
}
return &resources.StaleValue[any]{
Value: v,
StaleVersionFunc: func() uint32 {
return 0
},
}, nil
})
if err != nil {
return nil, err
}View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Specify the format explicitly: `transform.Unmarshal (dict "format" "csv") $str`.
- Print/inspect the string first (`{{ warnf "%s" $str }}`) — remote fetches often return HTML error bodies; check `.Err` on `resources.GetRemote` before unmarshaling.
- Validate the source data is well-formed JSON/TOML/YAML.
Example fix
{{/* before */}}
{{ $rows := transform.Unmarshal $csvString }}
{{/* after */}}
{{ $rows := transform.Unmarshal (dict "format" "csv") $csvString }} Defensive patterns
Strategy: validation
Validate before calling
{{ $s := trim $content " \n\t" }}
{{ if or (hasPrefix $s "{") (hasPrefix $s "[") (hasPrefix $s "<") (findRE `^[\w-]+\s*[:=]` $s) }}
{{ $data := transform.Unmarshal $s }}
{{ end }} Try / catch
{{ with try (transform.Unmarshal $s) }}
{{ with .Err }}{{ warnf "unknown data format, skipping: %s" . }}{{ else }}{{ $data := .Value }}{{ end }}
{{ end }} Prevention
- Unmarshal from Resources (which carry a media type) rather than raw strings so the format is detected from the MIME type, not sniffed
- When unmarshaling a raw string, make sure it is actually well-formed JSON/TOML/YAML/XML/CSV — empty strings and HTML bodies trigger this error
- Check remote responses for error pages (HTML) before unmarshaling API results
When it happens
Trigger: `{{ transform.Unmarshal $someString }}` where the string doesn't start with recognizable JSON/TOML/YAML/XML/CSV structure — e.g. plain prose, HTML, an error page body, or an empty-ish/whitespace-padded fragment.
Common situations: A remote API call returned an HTML error page or empty body instead of JSON (rate limiting, auth failure) and the body string was piped to unmarshal; unmarshaling CSV without specifying format (CSV can't be sniffed reliably); truncated or corrupted data files.
Related errors
- unmarshal takes 1 or 2 arguments
- first argument must be a map
- failed to decode options: %w
- format %q not supported
- MIME %q not supported
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/f74c921ac4bf8b02.json.
Report an issue: GitHub ↗.