{"id":"44b2b70b0be72bb3","repo":"gohugoio/hugo","slug":"type-t-not-supported","errorCode":null,"errorMessage":"type %T not supported","messagePattern":"type %T not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/transform/unmarshal.go","lineNumber":121,"sourceCode":"\n\t\t\treturn &resources.StaleValue[any]{\n\t\t\t\tValue: v,\n\t\t\t\tStaleVersionFunc: func() uint32 {\n\t\t\t\t\treturn resource.StaleVersion(r)\n\t\t\t\t},\n\t\t\t}, nil\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn v.Value, nil\n\n\t}\n\n\tdataStr, err := types.ToStringE(data)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"type %T not supported\", data)\n\t}\n\n\tif strings.TrimSpace(dataStr) == \"\" {\n\t\treturn nil, nil\n\t}\n\n\tkey := hashing.XxHashFromStringHexEncoded(dataStr)\n\n\tif decoder != metadecoders.Default {\n\t\tkey += decoder.OptionsKey()\n\t}\n\n\tv, err := ns.cacheUnmarshal.GetOrCreate(key, func(string) (*resources.StaleValue[any], error) {\n\t\tvar f metadecoders.Format\n\t\tif decoder.Format != \"\" {\n\t\t\tf = metadecoders.FormatFromString(decoder.Format)\n\t\t\tif f == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"format %q not supported\", decoder.Format)","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/transform/unmarshal.go#L103-L139","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"{{/* before */}}\n{{ $d := site.Data.config | transform.Unmarshal }}\n{{/* after */}}\n{{ $d := site.Data.config }}{{/* already decoded */}}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"{{/* Unmarshal accepts only strings, []byte, or Resources */}}\n{{ if or (reflect.IsMap . | not) (eq (printf \"%T\" .) \"string\") }}...{{ end }}\n{{/* simplest: coerce first */}}\n{{ $data := transform.Unmarshal (string $input) }}","tryCatchPattern":"{{ with try (transform.Unmarshal $input) }}\n  {{ with .Err }}{{ errorf \"cannot unmarshal %T: %s\" $input . }}{{ else }}{{ $data := .Value }}{{ end }}\n{{ end }}","preventionTips":["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"],"tags":["hugo","templates","unmarshal","type-error"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}