gohugoio/hugo · error
failed to create resource for path %q, expected a resource.R
Error message
failed to create resource for path %q, expected a resource.Resource, got %T
What it means
`Spec.NewResourceWrapperFromResourceConfig` in resources/resource_spec.go wraps an already-existing resource declared in front matter. It type-switches on `rc.Content.Value` and only accepts a `resource.Resource`; anything else means the front matter asked Hugo to wrap something that isn't a resource, and it reports the path plus the actual Go type. This path is distinct from creating a resource from literal content — that goes through `NewResource`.
Source
Thrown at resources/resource_spec.go:169
FileCaches filecache.Caches
// Assets used after the build is done.
// This is shared between all sites.
*PostBuildAssets
}
type PostBuildAssets struct {
PostProcessResources *maphelpers.ConcurrentMap[string, postpub.PostPublishedResource]
JSConfigBuilder *jsconfig.Builder
}
func (r *Spec) NewResourceWrapperFromResourceConfig(rc *pagemeta.ResourceConfig) (resource.Resource, error) {
content := rc.Content
switch r := content.Value.(type) {
case resource.Resource:
return cloneWithMetadataFromResourceConfigIfNeeded(rc, r), nil
default:
return nil, fmt.Errorf("failed to create resource for path %q, expected a resource.Resource, got %T", rc.PathInfo.Path(), content.Value)
}
}
// NewResource creates a new Resource from the given ResourceSourceDescriptor.
func (r *Spec) NewResource(rd ResourceSourceDescriptor) (resource.Resource, error) {
if err := rd.init(r); err != nil {
return nil, err
}
dir, name := path.Split(rd.TargetPath)
dir = paths.ToSlashPreserveLeading(dir)
if dir == "/" {
dir = ""
}
rp := internal.ResourcePaths{
File: name,
Dir: dir,
BaseDirTarget: rd.BasePathTargetPath,View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Resolve the value to an actual resource first (e.g. `resources.Get` or `.Resources.GetMatch`) and assign that object to `content.value`.
- If you intended literal inline content rather than wrapping an existing resource, use the inline-content form with `content.mediaType` + string `value` so Hugo takes the create path instead of the wrap path.
- Check the `%T` in the message — `string` almost always means a path was passed where the resolved Resource was expected.
- Guard against nil: a failed `resources.Get` returns nil, which will also land here, so check the lookup succeeded before assigning.
Example fix
{{/* before */}}
{{ $rc := dict "path" "images/hero.jpg" "content" (dict "value" "images/hero.jpg") }}
{{/* after */}}
{{ $r := resources.Get "images/hero.jpg" }}
{{ with $r }}
{{ $rc := dict "path" "images/hero.jpg" "content" (dict "value" .) }}
{{ end }} Defensive patterns
Strategy: type-guard
Type guard
// when implementing custom resource factories, guarantee a resource.Resource
func asResource(v any) (resource.Resource, bool) {
r, ok := v.(resource.Resource)
return r, ok
} Prevention
- Ensure paths passed to resources.Get/GetMatch point to real files under assets/
- Don't pass directories or empty paths where a file resource is expected
- If extending Hugo, make factory functions return a concrete type satisfying resource.Resource
When it happens
Trigger: A page-resource entry in front matter whose `content.value` is a plain string, map, or number where a resource object was required by the code path (resource wrapping rather than resource creation); or template/module code building a `pagemeta.ResourceConfig` and passing a non-Resource value into `Content.Value` before calling `NewResourceWrapperFromResourceConfig`.
Common situations: Programmatically constructing page resources from a data file or template and forgetting to resolve the value through `resources.Get`/`.Resources.Get` first, so a path string is passed instead of the Resource; mixing the two front matter styles (inline literal content vs. referencing an existing resource) in one entry.
Related errors
- media type %q not found
- content source: failed to convert %T to string: %s
- error processing file %q
- failed to parse file %q: %s
- failed to convert metadata for file %q: %s
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/c4feffaa6cf1cd24.json.
Report an issue: GitHub ↗.