gohugoio/hugo · error

no Key set in Resource

Error message

no Key set in Resource

What it means

Thrown by transform.Unmarshal when the data argument is a Resource (implements UnmarshableResource) but its Key() returns an empty string (tpl/transform/unmarshal.go:64-67). The Key is used for caching the unmarshalled result; an empty key would defeat caching and is treated as a misconfiguration.

Source

Thrown at tpl/transform/unmarshal.go:67

		m, ok := args[0].(map[string]any)
		if !ok {
			return nil, errors.New("first argument must be a map")
		}

		var err error

		data = args[1]
		decoder, err = decodeDecoder(m)
		if err != nil {
			return nil, fmt.Errorf("failed to decode options: %w", err)
		}
	}

	if r, ok := data.(resource.UnmarshableResource); ok {
		key := r.Key()

		if key == "" {
			return nil, errors.New("no Key set in Resource")
		}

		if decoder != metadecoders.Default {
			key += decoder.OptionsKey()
		}

		v, err := ns.cacheUnmarshal.GetOrCreate(key, func(string) (*resources.StaleValue[any], error) {
			var f metadecoders.Format
			if decoder.Format != "" {
				f = metadecoders.FormatFromString(decoder.Format)
				if f == "" {
					return nil, fmt.Errorf("format %q not supported", decoder.Format)
				}
			} else {
				f = metadecoders.FormatFromStrings(r.MediaType().Suffixes()...)
				if f == "" {
					return nil, fmt.Errorf("MIME %q not supported", r.MediaType())
				}

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Ensure the resource has a Key by giving it a path: use resources.GetRemote with a key, or name the resource so a key is derived.
  2. If the resource is built via resources.FromString, materialize it through a pipeline step that assigns a key.
  3. Alternatively, read the resource content into a string and Unmarshal the string instead of the Resource.

Example fix

// before
{{ $r := resources.FromString "tmp" .Raw }}
{{ transform.Unmarshal $r }}
// after
{{ transform.Unmarshal $r.Content }}
Defensive patterns

Strategy: validation

Validate before calling

{{/* Prefer Unmarshalling a string, or ensure the Resource has a Key */}}
{{ transform.Unmarshal $r.Content }}

Prevention

When it happens

Trigger: Calling {{ transform.Unmarshal .Resource }} (or with options) where .Resource is a dynamically created resource (e.g. from resources.FromString) that has no Key/Permalink set.

Common situations: Using resources.FromString or resources.Concat without assigning a name/key; passing a remote resource fetched without a key; resources created in templates that bypass the resource system's key assignment.

Related errors


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