gohugoio/hugo · critical

resource %d to post process is nil

Error message

resource %d to post process is nil

What it means

Panic during post-publish resource substitution: iterating over the collected toPostProcess resources, an entry r is nil. Post-process resources are those marked with a post-publish placeholder (e.g. | SAFEHTMLURL or css.Suffix style references resolved after publish); a nil entry means the PostProcessResources map was populated with a nil value. This is an internal invariant failure.

Source

Thrown at hugolib/hugo_sites_build.go:732

		k := 0
		changed := false

		for {
			l := bytes.Index(content[k:], []byte(postpub.PostProcessPrefix))
			if l == -1 {
				break
			}
			m := bytes.Index(content[k+l:], []byte(postpub.PostProcessSuffix)) + len(postpub.PostProcessSuffix)

			low, high := k+l, k+l+m

			field := content[low:high]

			forward := l + m

			for i, r := range toPostProcess {
				if r == nil {
					panic(fmt.Sprintf("resource %d to post process is nil", i+1))
				}
				v, ok := r.GetFieldString(string(field))
				if ok {
					content = append(content[:low], append([]byte(v), content[high:]...)...)
					changed = true
					forward = len(v)
					break
				}
			}

			k += forward
		}

		if changed {
			return afero.WriteFile(h.BaseFs.PublishFs, filename, content, 0o666)
		}

		return nil

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Clean the build (remove public/, resources/_gen, build lock) and rebuild from scratch.
  2. Audit templates that use post-process resource placeholders for a resource that could be nil (guard with 'with' / 'if').
  3. Upgrade Hugo to the current release; report if it reproduces with a minimal project.

Example fix

{{/* before: resource may be nil but is registered for post-process */}}
{{ $css := resources.Get "main.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.Permalink }}">

{{/* after: guard so nil is never registered */}}
{{ with resources.Get "main.css" }}
  {{ $css := . | minify | fingerprint }}
  <link rel="stylesheet" href="{{ $css.Permalink }}">
{{ end }}
Defensive patterns

Strategy: validation

Validate before calling

// In templates, guard resource lookups so nil is never registered for post-processing:
//   {{ with resources.Get "main.css" }}{{ $css := . | minify }}<link href="{{ $css.Permalink }}">{{ end }}
// Programmatically, ensure any resource registered in PostProcessResources is non-nil.

Try / catch

// Wrap the build in a recover() to convert the panic to an error (see 781).

Prevention

When it happens

Trigger: A template/resource marks a resource for post-processing but the resource object becomes nil before the publish substitution pass (e.g. a resource lookup returned nil and was still registered). Concurrent mutation of the PostProcessResources concurrent map. A custom output/resource type that does not satisfy the expected interface.

Common situations: Using resource post-publish features (e.g. minify/css/js pipe with post-process placeholders) where a referenced resource is missing or failed to create. Incremental build staleness after deleting a resource. Hugo version mismatch.

Related errors


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