gohugoio/hugo · error

type %T not supported in Resource transformations

Error message

type %T not supported in Resource transformations

What it means

A resource transformation template function (css.Sass, js.Build, minify, etc.) received a single argument that does not implement resources.ResourceTransformer. In ResolveArgs the len(args)==1 branch type-asserts args[0] and reports its concrete type when the assertion fails. See helpers.go:47-52.

Solutions

  1. Ensure the value passed is a Hugo Resource obtained via resources.Get, resources.GetRemote, or resources.FromString.
  2. Guard against nil using {{ with $r }}...{{ end }} before transforming.
  3. Confirm the source asset exists under the assets mount or the remote fetch succeeded.

Example fix

// before
{{ $css := css.Sass "main.scss" }}

// after
{{ $r := resources.Get "main.scss" }}
{{ with $r }}{{ $css := $r | css.Sass }}{{ end }}
Defensive patterns

Strategy: type-guard

Validate before calling

// In Go: ensure the value satisfies the interface before transforming.
func isResourceTransformer(v any) bool {
    _, ok := v.(resources.ResourceTransformer)
    return ok
}

Type guard

// In templates: guard nil/non-resources before transforming.
{{ with $r := resources.Get "main.scss" }}
  {{ $r | css.Sass }}
{{ else }}
  {{ warnf "resource not found" }}
{{ end }}

Prevention

When it happens

Trigger: {{ css.Sass "main.scss" }} passing a plain string, or {{ (nil) | css.Sass }} where resources.Get returned nil because the asset was not found.

Common situations: resources.Get/GetRemote returned nil (missing file) and nil is piped into a transform; passing a URL or filename string instead of the Resource object.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/104d69fb1a6987aa. Report an issue: GitHub.

Appendix: source

Thrown at tpl/internal/resourcehelpers/helpers.go:50

	v1, ok1 := args[0].(string)
	if !ok1 {
		return nil, "", false
	}
	v2, ok2 := args[1].(resources.ResourceTransformer)

	return v2, v1, ok2
}

// This roundabout way of doing it is needed to get both pipeline behavior and options as arguments.
func ResolveArgs(args []any) (resources.ResourceTransformer, map[string]any, error) {
	if len(args) == 0 {
		return nil, nil, errors.New("no Resource provided in transformation")
	}

	if len(args) == 1 {
		r, ok := args[0].(resources.ResourceTransformer)
		if !ok {
			return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
		}
		return r, nil, nil
	}

	r, ok := args[1].(resources.ResourceTransformer)
	if !ok {
		if _, ok := args[1].(map[string]any); !ok {
			return nil, nil, fmt.Errorf("no Resource provided in transformation")
		}
		return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
	}

	m, err := hmaps.ToStringMapE(args[0])
	if err != nil {
		return nil, nil, fmt.Errorf("invalid options type: %w", err)
	}

	return r, m, nil

View on GitHub (pinned to 52c9bd7908)