gohugoio/hugo · error

ErrShutdown

ErrShutdown

Error message

dispatcher is shutting down

What it means

ErrShutdown (internal/warpc/warpc.go:201) is returned by the warpc dispatcher pool when a call is attempted or in flight while the pool of WASM worker processes (used for katex, AVIF, WebP, etc.) is being closed. It signals that the RPC layer is tearing down, not that the request itself was invalid.

Source

Thrown at internal/warpc/warpc.go:201

	stdout       io.WriteCloser
	stdoutBinary hugio.ReadWriteCloser
	dec          *json.Decoder
	enc          *json.Encoder
}

func (p *inOut) Close() error {
	if err := p.stdin.Close(); err != nil {
		return err
	}

	// This will also close the underlying writers.
	if err := p.stdout.Close(); err != nil {
		return err
	}
	return nil
}

var ErrShutdown = fmt.Errorf("dispatcher is shutting down")

var timerPool = sync.Pool{}

func getTimer(d time.Duration) *time.Timer {
	if v := timerPool.Get(); v != nil {
		timer := v.(*time.Timer)
		timer.Reset(d)
		return timer
	}
	return time.NewTimer(d)
}

func putTimer(t *time.Timer) {
	if !t.Stop() {
		select {
		case <-t.C:
		default:
		}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Scroll up in the log for the first error — an earlier WASM module failure usually closed the pool; fix that root cause.
  2. If it only occurs on interrupt/shutdown, it's benign; ignore it.
  3. Re-run the build; if it reproduces cleanly, upgrade Hugo and report the sequence of errors.
Defensive patterns

Strategy: type-guard

Type guard

func isShutdown(err error) bool { return errors.Is(err, warpc.ErrShutdown) }

Try / catch

res, err := d.Execute(ctx, msg)
if errors.Is(err, warpc.ErrShutdown) {
    // dispatcher closed (build teardown) — stop submitting work, do not retry
    return err
}

Prevention

When it happens

Trigger: dispatcherPool.Execute or send() racing with pool Close() — e.g. image/katex rendering still running while Hugo shuts down, a fatal error in one dispatcher triggering pool teardown, or a server rebuild closing the pool mid-render.

Common situations: Ctrl-C or build abort while templates are still rendering math/images; a preceding WASM module crash (look for earlier errors in the log — this one is often the secondary symptom); very long builds where an earlier fatal dispatcher error closed the pool.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/83900b20b7e03027.json. Report an issue: GitHub ↗.