gohugoio/hugo · error

walk: open: path: filename

Error message

walk: open: path: %q filename: %q: %s

What it means

Emitted by Walkway.walk when fs.Open on a directory it is about to descend into fails, after checkErr declines to swallow it. The message includes both the logical path and the resolved Meta().Filename so the caller can tell which mount/overlay file refused to open. Format: 'walk: open: path: %q filename: %q: %s'.

Solutions

  1. Compare the logical path vs filename in the message to find which mount layer refused Open.
  2. Ensure the process user has open/execute permission on every directory in the walked tree.
  3. Leave FailOnNotExist at its false default so transiently-absent dirs are skipped and logged rather than fatal.
  4. Pause file generators (sync, rsync, IDE indexers) that rename/remove directories during the build.
Defensive patterns

Strategy: validation

Validate before calling

for _, d := range requiredDirs {
    f, err := fs.Open(d)
    if err != nil { /* preflight: fix perms/availability before Walk */ }
    f.Close()
}

Try / catch

if err := walkway.Walk(); err != nil {
    if strings.Contains(err.Error(), "walk: open:") {
        // parse the path/filename fields, verify perms, then optionally retry once
    }
}

Prevention

When it happens

Trigger: During a recursive walk, a directory entry identified by Stat cannot be Opened — e.g. it was removed between Stat and Open, permission denied on Open despite readable Stat, or an overlay/mount layer that Stats but cannot Open a synthetic directory. FailOnNotExist=true turns a vanished dir into this error instead of a skip.

Common situations: Build server running under a different user than the content checkout (Stat ok, Open denied); a content mount backed by an afero overlay whose source dir was swapped; editor/IDE renaming a directory mid `hugo server` watch rebuild.

Related errors


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

Appendix: source

Thrown at hugofs/walk.go:162

	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)
		if err != nil {
			if w.checkErr(path, err) {
				return nil
			}
			return fmt.Errorf("walk: open: path: %q filename: %q: %s", path, info.Meta().Filename, err)
		}
		fis, newCtx, err := ReadDirWithContext(ctx, f, -1)
		ctx = newCtx

		f.Close()
		if err != nil {
			if w.checkErr(path, err) {
				return nil
			}
			return fmt.Errorf("walk: Readdir: %w", err)
		}

		dirEntries = DirEntriesToFileMetaInfos(fis)
		for _, fi := range dirEntries {
			if fi.Meta().PathInfo == nil {
				fi.Meta().PathInfo = w.cfg.PathParser.Parse("", filepath.Join(pathRel, fi.Name()))
			}
		}

View on GitHub (pinned to 52c9bd7908)