{"id":"9fe5200689ebf8cd","repo":"gohugoio/hugo","slug":"cannot-transform-content-of-resource-of-type-t","errorCode":null,"errorMessage":"cannot transform content of Resource of type %T","messagePattern":"cannot transform content of Resource of type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"resources/transform.go","lineNumber":836,"sourceCode":"\n// We will persist this information to disk.\ntype transformedResourceMetadata struct {\n\tTarget     string         `json:\"Target\"`\n\tMediaTypeV string         `json:\"MediaType\"`\n\tMetaData   map[string]any `json:\"Data\"`\n}\n\n// contentReadSeekerCloser returns a ReadSeekerCloser if possible for a given Resource.\nfunc contentReadSeekerCloser(r resource.Resource) (hugio.ReadSeekCloser, error) {\n\tswitch rr := r.(type) {\n\tcase resource.ReadSeekCloserResource:\n\t\trc, err := rr.ReadSeekCloser()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn rc, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"cannot transform content of Resource of type %T\", r)\n\n\t}\n}\n","sourceCodeStart":818,"sourceCodeEnd":840,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/resources/transform.go#L818-L840","documentation":"`contentReadSeekerCloser` in resources/transform.go opens a resource's bytes for a transformation step. It only handles resources implementing `resource.ReadSeekCloserResource`; anything else cannot have its content read, so the transformation is refused with the concrete type in `%T`. Image resources produced by certain pipelines and some wrapper/remote types don't implement this interface.","triggerScenarios":"Chaining a content-level transform — `resources.Minify`, `css.Sass`/`css.PostCSS`, `js.Build`, `resources.ExecuteAsTemplate`, `| replaceRE` style transforms — onto a resource whose concrete type isn't readable, e.g. the output of an image transform, a resource constructed by a custom module, or a resource wrapper created from front matter metadata.","commonSituations":"Piping an image resource (`.Resize`, `.Fill`) into a text transform by mistake; applying `resources.ExecuteAsTemplate` to a resource from `resources.GetRemote` that failed and returned an unexpected type; custom Go modules implementing `resource.Resource` without `ReadSeekCloser`.","solutions":["Check the pipeline order — only apply text/content transforms to text-like resources; move image transforms to the end of the chain.","Inspect the `%T` in the message to identify which concrete resource type entered the transform, then trace back to where it was created in your templates.","Re-fetch the source with `resources.Get`/`resources.GetRemote` (checking `.Err`) so a readable resource enters the transform rather than a derived one.","If you own the resource type in a Go module, implement `resource.ReadSeekCloserResource` so it can participate in content transforms."],"exampleFix":"{{/* before — image result piped into a text transform */}}\n{{ $r := resources.Get \"img/logo.png\" | images.Resize \"200x\" | minify }}\n\n{{/* after */}}\n{{ $r := resources.Get \"img/logo.png\" | images.Resize \"200x\" }}","handlingStrategy":"type-guard","validationCode":"// only pipe transformable resources into resources.Minify/PostCSS/etc.\n{{ $r := resources.Get \"css/main.css\" }}\n{{ if $r }}{{ $r = $r | minify }}{{ end }}","typeGuard":"// template-level guard: check the resource came from the asset pipeline\n{{ if and $r (ne $r.ResourceType \"\") }}...{{ end }}","tryCatchPattern":null,"preventionTips":["Only apply transforms (minify, fingerprint, postCSS) to resources obtained from resources.Get/GetMatch or page resources","Don't feed page objects or plain strings into resource transform functions","Use resources.FromString to wrap raw strings before transforming them"],"tags":["hugo","resource-pipeline","transform","templates","type-error"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}