gohugoio/hugo · error
cannot transform content of Resource of type %T
Error message
cannot transform content of Resource of type %T
What it means
Returned by contentReadSeekCloser when a resource being transformed does not implement resource.ReadSeekCloserResource. Transformations need a ReadSeeker to re-read content (e.g. for caching, integrity, multi-pass transforms); resources that only expose a one-shot reader cannot be transformed and hit the default branch with %T.
Solutions
- Ensure the resource is seekable — materialize it first (e.g. fetch and cache the remote resource, or copy into a resource that implements ReadSeekCloserResource).
- Use resources.Get followed by a clone/copy that supports ReadSeekCloser before transforming.
- If implementing a custom resource type, implement resource.ReadSeekCloserResource (ReadSeekCloser() method) so it can be transformed.
Example fix
// before
{{ $r := resources.GetRemote "https://example.com/style.css" }}
{{ $x := $r | minify }} // cannot transform content of Resource of type *remoteResource
// after
{{ $r := resources.GetRemote "https://example.com/style.css" | resources.Copy "style.css" }}
{{ $x := $r | minify }} Defensive patterns
Strategy: type-guard
Validate before calling
// Guard that a resource is transformable (seekable) before transforming.
func isTransformable(r resource.Resource) bool {
_, ok := r.(resource.ReadSeekCloserResource)
return ok
} Type guard
// Go type guard for ReadSeekCloserResource.
func asSeekable(r resource.Resource) (resource.ReadSeekCloserResource, bool) {
s, ok := r.(resource.ReadSeekCloserResource)
return s, ok
} Prevention
- Materialize remote/one-shot resources (resources.Copy / fetch+cache) before transforming.
- When implementing custom resource types, implement ReadSeekCloserResource.
- Check the interface before chaining many transforms to fail with a clearer message.
When it happens
Trigger: Calling a transformation (TransformWithContext/Transform) on a resource type that does not implement ReadSeekCloserResource — for example a remote-only resource, a constructed resource without seek support, or a post-publish resource that wasn't wrapped with ReadSeekCloser capability.
Common situations: Passing a resource obtained from resources.GetRemote (without caching) into a transform that needs seek; wrapping a reader-only adapter as a resource; transforming a remote/headless bundle resource directly.
Related errors
- failed to create resource for path
- format not supported
- MIME not supported
- failed to add internal partial decorator template
- failed to create internal partial decorator template
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/9fe5200689ebf8cd.
Report an issue: GitHub.
Appendix: source
Thrown at resources/transform.go:837
// We will persist this information to disk.
type transformedResourceMetadata struct {
Target string `json:"Target"`
MediaTypeV string `json:"MediaType"`
MetaData map[string]any `json:"Data"`
}
// contentReadSeekerCloser returns a ReadSeekerCloser if possible for a given Resource.
func contentReadSeekerCloser(r resource.Resource) (hugio.ReadSeekCloser, error) {
switch rr := r.(type) {
case resource.ReadSeekCloserResource:
rc, err := rr.ReadSeekCloser()
if err != nil {
return nil, err
}
return rc, nil
default:
return nil, fmt.Errorf("cannot transform content of Resource of type %T", r)
}
}
View on GitHub (pinned to 52c9bd7908)