{"id":"c05d9e813b42c25a","repo":"gohugoio/hugo","slug":"format-q-not-supported","errorCode":null,"errorMessage":"format %q not supported","messagePattern":"format %q not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/transform/unmarshal.go","lineNumber":79,"sourceCode":"\t}\n\n\tif r, ok := data.(resource.UnmarshableResource); ok {\n\t\tkey := r.Key()\n\n\t\tif key == \"\" {\n\t\t\treturn nil, errors.New(\"no Key set in Resource\")\n\t\t}\n\n\t\tif decoder != metadecoders.Default {\n\t\t\tkey += decoder.OptionsKey()\n\t\t}\n\n\t\tv, err := ns.cacheUnmarshal.GetOrCreate(key, func(string) (*resources.StaleValue[any], error) {\n\t\t\tvar f metadecoders.Format\n\t\t\tif decoder.Format != \"\" {\n\t\t\t\tf = metadecoders.FormatFromString(decoder.Format)\n\t\t\t\tif f == \"\" {\n\t\t\t\t\treturn nil, fmt.Errorf(\"format %q not supported\", decoder.Format)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tf = metadecoders.FormatFromStrings(r.MediaType().Suffixes()...)\n\t\t\t\tif f == \"\" {\n\t\t\t\t\treturn nil, fmt.Errorf(\"MIME %q not supported\", r.MediaType())\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treader, err := r.ReadSeekCloser()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdefer reader.Close()\n\n\t\t\tb, err := io.ReadAll(reader)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/transform/unmarshal.go#L61-L97","documentation":"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.","triggerScenarios":"`{{ 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.","commonSituations":"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).","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."],"exampleFix":"<!-- before -->\n{{ transform.Unmarshal (dict \"format\" \"ymal\") $r }}\n<!-- after -->\n{{ transform.Unmarshal (dict \"format\" \"yaml\") $r }}","handlingStrategy":"validation","validationCode":"{{ $ext := path.Ext $file | strings.TrimPrefix \".\" }}\n{{ if in (slice \"json\" \"yaml\" \"yml\" \"toml\" \"csv\" \"xml\") $ext }}{{ $d := unmarshal $content }}{{ else }}{{ errorf \"cannot unmarshal %q\" $file }}{{ end }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["hugo","templates","unmarshal","format"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}