gohugoio/hugo · error

must provide one or more Resource objects to concat

Error message

must provide one or more Resource objects to concat

What it means

Thrown by resources.Concat when the provided slice of resources is empty after conversion. Concat requires at least one Resource (typically more) to bundle into a single output. An empty slice, an empty .Resources collection, or a filtered collection that matched nothing produces this.

Solutions

  1. Guard the call so Concat only runs when there is at least one resource: {{ if $assets }}{{ resources.Concat "bundle.css" $assets }}{{ end }}.
  2. Verify your resources.Match/GetMatch pattern actually returns files.
  3. Default to a fallback asset when the collection is empty.

Example fix

// before
{{ resources.Concat "bundle.css" ($assets | where ".RelPermalink" "ne" "") }}
// after
{{ $bundle := $assets | where ".RelPermalink" "ne" "" }}
{{ with $bundle }}{{ resources.Concat "bundle.css" . }}{{ end }}
Defensive patterns

Strategy: validation

Validate before calling

{{ with $assets }}{{ if gt (len .) 0 }}{{ resources.Concat "bundle.css" . }}{{ end }}{{ end }}

Prevention

When it happens

Trigger: Calling {{ resources.Concat "bundle.css" slice }}, {{ resources.Concat "out.js" ($assets | where ... ) }} where the filter matches nothing, or concatenating an empty .Resources.

Common situations: Conditional bundling where no files matched the glob/filter on some pages; iterating and collecting resources into a slice that ends up empty; typo in a Match pattern that returns nothing.

Related errors


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

Appendix: source

Thrown at tpl/resources/resources.go:222

func (ns *Namespace) Concat(targetPathIn any, r any) (resource.Resource, error) {
	targetPath, err := cast.ToStringE(targetPathIn)
	if err != nil {
		return nil, err
	}

	var rr resource.Resources

	switch v := r.(type) {
	case resource.Resources:
		rr = v
	case resource.ResourcesConverter:
		rr = v.ToResources()
	default:
		return nil, fmt.Errorf("expected slice of Resource objects, received %T instead", r)
	}

	if len(rr) == 0 {
		return nil, errors.New("must provide one or more Resource objects to concat")
	}

	return ns.bundlerClient.Concat(targetPath, rr)
}

// FromString creates a Resource from a string published to the relative target path.
func (ns *Namespace) FromString(targetPathIn, contentIn any) (resource.Resource, error) {
	targetPath, err := cast.ToStringE(targetPathIn)
	if err != nil {
		return nil, err
	}
	content, err := cast.ToStringE(contentIn)
	if err != nil {
		return nil, err
	}

	return ns.createClient.FromString(targetPath, content)
}

View on GitHub (pinned to 52c9bd7908)