gohugoio/hugo · error

postProcess: %w

Error message

postProcess: %w

What it means

Hugo wraps this around any failure in the post-processing build pass (HugoSites.postProcess), which runs after all pages are rendered. That pass writes the jsconfig.json for JS IntelliSense, and — more importantly — resolves every resource flagged for post-publish: deferred asset transforms (toCSS, PostCSS, babel, minify) and per-page resource publishing that were deferred during render. The %w carries the real underlying cause, so this string is only the outer label for a pipeline/publish failure.

Source

Thrown at hugolib/hugo_sites_build.go:222

			return err
		}

		// We need to do this before render deferred.
		if err := h.printPathWarningsOnce(); err != nil {
			h.SendError(fmt.Errorf("printPathWarnings: %w", err))
		}

		if err := h.renderDeferred(infol); err != nil {
			h.SendError(fmt.Errorf("renderDeferred: %w", err))
		}

		// This needs to be done after the deferred rendering to get complete template usage coverage.
		if err := h.printUnusedTemplatesOnce(); err != nil {
			h.SendError(fmt.Errorf("printPathWarnings: %w", err))
		}

		if err := h.postProcess(infol); err != nil {
			h.SendError(fmt.Errorf("postProcess: %w", err))
		}
	}

	if h.Metrics != nil {
		var b bytes.Buffer
		h.Metrics.WriteMetrics(&b)

		h.Log.Printf("\nTemplate Metrics:\n\n")
		h.Log.Println(b.String())
	}

	h.StopErrorCollector()

	err := <-errs
	if err != nil {
		return err
	}

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Read the wrapped error after the colon — the %w is the actual cause (e.g. 'postcss: command not found', 'file does not exist').
  2. Install/verify the external binary the transform needs: `npm i -D postcss postcss-cli` (or dart-sass / esbuild) and ensure it resolves on PATH.
  3. Run `npm install` in the project root so node_modules the pipeline imports exist.
  4. Confirm the asset source path passed to the pipeline exists and is readable.
  5. Check the output/publish directory is writable and not locked by another process.

Example fix

// before
{{ $css := resources.Get "css/main.scss" | toCSS }}
// postProcess error if postcss/sass binary missing

// after: ensure toolchain present
//   npm i -D postcss postcss-cli   (or dart-sass for scss)
{{ $css := resources.Get "css/main.scss" | css.Sass }}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-build: verify external toolchain the pipeline needs exists
import "os/exec"
func toolReady(name string) bool { _, err := exec.LookPath(name); return err == nil }
// if !toolReady("postcss") { return fmt.Errorf("install postcss-cli") }

Try / catch

if err := sites.Build(cfg); err != nil {
    var pe *hugofs.PathError
    if errors.As(err, &pe) { /* file/permission cause */ }
    return err // surface wrapped postProcess cause to the user
}

Prevention

When it happens

Trigger: An asset pipeline resource (resources.PostCSS, resources.ToCSS, js.Build, babel) cannot complete; an image/resource fails its Publish() call; a deferred post-process placeholder in rendered HTML cannot be resolved; a post-publish Resource.Publisher returns an error. Emitted at hugo_sites_build.go:222 via h.SendError.

Common situations: postcss-cli / dart-sass / esbuild not installed or not on PATH; node_modules missing (forgot `npm install`); a broken or non-existent asset input path passed to a transform; publishing into a read-only or locked output directory; a template uses `.RelPermalink` on a resource whose transform failed earlier and was deferred.

Related errors


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