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
- Read the wrapped error after the colon — the %w is the actual cause (e.g. 'postcss: command not found', 'file does not exist').
- Install/verify the external binary the transform needs: `npm i -D postcss postcss-cli` (or dart-sass / esbuild) and ensure it resolves on PATH.
- Run `npm install` in the project root so node_modules the pipeline imports exist.
- Confirm the asset source path passed to the pipeline exists and is readable.
- 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
- Pin and install every asset toolchain (postcss-cli, dart-sass, esbuild) the templates reference.
- Run `npm install` in CI before `hugo` so node_modules exist.
- Make the publish/output directory writable.
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
- no sites to build
- resources.PostProcess cannot be used in a deferred template
- error copying static files: %w
- error building site: %w
- failed to compile cache buster %q: %w
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/2c3246b7a3c82ccd.
Report an issue: GitHub.