gohugoio/hugo · error

walk: stat

Error message

walk: stat: %s

What it means

Emitted by Walkway.walk (hugofs/walk.go) when fs.Stat on a walked path fails and the failure is neither the root-not-exist case nor suppressed by checkErr (FailOnNotExist=false). It formats the raw stat error as 'walk: stat: %s'. This is the generic non-Exist stat failure during recursive directory descent.

Solutions

  1. Check the permissions/ownership of the path named in the error and its parents.
  2. If the path is legitimately optional, do not set WalkwayConfig.FailOnNotExist=true (default tolerates absence).
  3. Resolve broken symlinks in the mount or exclude them from the walk root.
  4. Re-run after stabilizing the source tree (stop concurrent file generators that delete mid-walk).

Example fix

// before
cfg := hugofs.WalkwayConfig{ Fs: fs, Root: root, FailOnNotExist: true, WalkFn: fn }
// after
cfg := hugofs.WalkwayConfig{ Fs: fs, Root: root, FailOnNotExist: false, WalkFn: fn }
Defensive patterns

Strategy: validation

Validate before calling

info, err := walkFs.Stat(root)
if err != nil {
    if herrors.IsNotExist(err) && !cfg.FailOnNotExist { /* ok, will return nil */ }
    else { /* will become 'walk: stat: %s' — fix permissions/path first */ }
}

Try / catch

err := walkway.Walk()
if err != nil && strings.Contains(err.Error(), "walk: stat:") {
    // re-stat the offending path to classify (perm vs gone) before retry
}

Prevention

When it happens

Trigger: Walkway.Walk descends into a path whose Stat returns a non-IsNotExist error (e.g. EACCES permission denied, EIO), OR returns IsNotExist while WalkwayConfig.FailOnNotExist is true. Triggered by any Hugo code path that walks a mounted filesystem (content, layouts, assets, archetypes).

Common situations: Content/asset mount points to a directory with restrictive permissions; a file is deleted between the directory listing and the per-entry Stat; a symlink with a broken target on a filesystem that reports it as a stat error rather than not-exist; FailOnNotExist=true set explicitly while the path genuinely is absent.

Related errors


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

Appendix: source

Thrown at hugofs/walk.go:139

	return false
}

// walk recursively descends path, calling walkFn.
func (w *Walkway) walk(ctx context.Context, path string, info FileMetaInfo, dirEntries []FileMetaInfo) error {
	pathRel := strings.TrimPrefix(path, w.cfg.Root)

	if info == nil {
		var err error
		fi, err := w.cfg.Fs.Stat(path)
		if err != nil {
			if path == w.cfg.Root && herrors.IsNotExist(err) {
				return nil
			}
			if w.checkErr(path, err) {
				return nil
			}
			return fmt.Errorf("walk: stat: %s", err)
		}
		info = fi.(FileMetaInfo)
	}

	err := w.cfg.WalkFn(ctx, path, info)
	if err != nil {
		if info.IsDir() && err == filepath.SkipDir {
			return nil
		}
		return err
	}

	if !info.IsDir() {
		return nil
	}

	if dirEntries == nil {
		f, err := w.cfg.Fs.Open(path)

View on GitHub (pinned to 52c9bd7908)