{"record":{"id":"4f8391e9b876bcc5","repo":"gohugoio/hugo","slug":"type-t-is-not-a-resource","errorCode":null,"errorMessage":"type %T is not a Resource","messagePattern":"type %T is not a Resource","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"resources/resource.go","lineNumber":292,"sourceCode":"\tbaseResourceResource\n\tbaseResourceInternal\n\tresource.Staler\n}\n\ntype commonResource struct{}\n\n// Slice is for internal use.\n// for the template functions. See collections.Slice.\nfunc (commonResource) Slice(in any) (any, error) {\n\tswitch items := in.(type) {\n\tcase resource.Resources:\n\t\treturn items, nil\n\tcase []any:\n\t\tgroups := make(resource.Resources, len(items))\n\t\tfor i, v := range items {\n\t\t\tg, ok := v.(resource.Resource)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"type %T is not a Resource\", v)\n\t\t\t}\n\t\t\tgroups[i] = g\n\t\t\t{\n\t\t\t}\n\t\t}\n\t\treturn groups, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid slice type %T\", items)\n\t}\n}\n\ntype fileInfo interface {\n\tsetOpenSource(hugio.OpenReadSeekCloser)\n\tsetSourceFilenameIsHash(bool)\n\tsetTargetPath(internal.ResourcePaths)\n\tsize() int64\n\thashProvider\n}","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/resources/resource.go#L274-L310","documentation":"Returned by `commonResource.Slice` when iterating a `[]any` whose elements are not all `resource.Resource`. This is the resource-side adapter for `collections.Slice`, used to normalize heterogeneous template slices into `resource.Resources`. The per-element assertion at resource.go:290-292 fails on the first non-Resource element.","triggerScenarios":"A template calls `collections.Slice` (or a pipe through `apply`) on a list containing non-resource values -- e.g. mixing `.Resources` entries with strings or pages, or passing page resources alongside plain Pages.","commonSituations":"Templates that build a JS/CSS bundle from `.Resources` plus a hardcoded string path; partial reuse where the param is sometimes a Resource and sometimes a Page; `slice` template function called with mixed media inputs.","solutions":["Ensure every element of the input slice satisfies `resource.Resource` (filter out Pages/strings first).","Use `.Resources` directly or `resources.Get`/`resources.Match` to build the slice.","If you need to mix text, create a Resource first via `resources.FromString`."],"exampleFix":"// template -- before\n{{ $r := slice \"main.js\" $page.Resources.Get \"app.js\" }}\n\n// after\n{{ $r := slice (resources.Get \"js/main.js\") (resources.Get \"js/app.js\") }}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Go\nfunc isResource(v any) bool {\n\t_, ok := v.(resource.Resource)\n\treturn ok\n}\n// Template\n{{ $clean := slice }}\n{{ range $r := $input }}{{ if (eq (printf \"%T\" $r) \"*resources.resourceAdapter\") }}{{ $clean = $clean | append $r }}{{ end }}{{ end }}","tryCatchPattern":null,"preventionTips":["Build resource lists only from `resources.Get`/`resources.Match`/`.Resources`.","Wrap strings with `resources.FromString` before mixing into a resource list.","Filter with `where` in templates before passing to resource helpers."],"tags":["templates","resources","collections","type-mismatch"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}