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
- Check the permissions/ownership of the path named in the error and its parents.
- If the path is legitimately optional, do not set WalkwayConfig.FailOnNotExist=true (default tolerates absence).
- Resolve broken symlinks in the mount or exclude them from the walk root.
- 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
- Leave FailOnNotExist=false unless the path is mandatory.
- Ensure the process user can stat every node under the walk root.
- Resolve broken symlinks before building.
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)