gohugoio/hugo · error

rebuild called when not in watch mode

Error message

rebuild called when not in watch mode

What it means

initRebuild performs incremental-rebuild bookkeeping (resetting per-page build state, invalidating caches for changed files) and asserts the site config has watch mode enabled. Hitting it means an incremental rebuild path was entered — Build called with events or WhatChanged changes — while `Internal.Watch` is false, which is an internal invariant violation rather than a user config error.

Source

Thrown at hugolib/hugo_sites_build.go:263

	errorCount := h.Log.LoggCount(logg.LevelError) + loggers.Log().LoggCount(logg.LevelError)
	if errorCount > 0 {
		return fmt.Errorf("logged %d error(s)", errorCount)
	}

	return nil
}

// Build lifecycle methods below.
// The order listed matches the order of execution.

func (h *HugoSites) initSites() error {
	h.reset()
	return nil
}

func (h *HugoSites) initRebuild(config *BuildCfg) error {
	if !h.Configs.Base.Internal.Watch {
		return errors.New("rebuild called when not in watch mode")
	}

	h.pageTrees.treePagesResources.WalkPrefixRaw("", func(key string, n contentNode) (radix.WalkFlag, contentNode, error) {
		cnh.resetBuildState(n)
		return radix.WalkContinue, nil, nil
	})

	for _, s := range h.Sites {
		s.resetBuildState(config.WhatChanged.needsPagesAssembly)
	}

	h.reset()
	h.resetLogs()

	return nil
}

// process prepares the Sites' sources for a full or partial rebuild.

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. If embedding hugolib, enable watch in the config (`internal.watch = true` / the equivalent config option) before passing change events to Build.
  2. Alternatively, call a full Build (no events, nil WhatChanged) instead of an incremental rebuild.
  3. If it appears from plain `hugo server` usage, report it as a bug at github.com/gohugoio/hugo with steps to reproduce.

Example fix

// before: embedding hugolib
cfg := config.New()
// watch not set
h.Build(BuildCfg{}, events...)

// after
cfg.Set("internal", map[string]any{"watch": true})
h.Build(BuildCfg{}, events...)
Defensive patterns

Strategy: type-guard

Validate before calling

// only call rebuild paths when watching is on
if !cfg.Watching() {
    // do a full Build instead of a rebuild
}

Type guard

func canRebuild(cfg *allconfig.Config) bool { return cfg.Internal.Watch }

Prevention

When it happens

Trigger: HugoSites.Build invoked with filesystem events or a populated WhatChanged when the configuration wasn't built with watch enabled — typically only reachable from programmatic use of hugolib (tests, tools embedding Hugo) that pass change events without setting the watch flag.

Common situations: Developers embedding hugolib and calling Build with BuildCfg changes/events on a non-watch config; a Hugo bug where a rebuild is triggered after the server's watch config was torn down. Normal CLI users should essentially never see this.

Related errors


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