gohugoio/hugo · error
fileInfo: %w
Error message
fileInfo: %w
What it means
Wrapped by fileInfo.Open() when the underlying source file metadata's Open() call fails. The fileInfo struct wraps a source.File; calling Open() delegates to the file's FileInfo().Meta().Open() and re-wraps any error with the 'fileInfo:' prefix for tracing. It is a low-level I/O failure surfaced while Hugo reads a content/source file (e.g. during page reads or the source walk).
Source
Thrown at hugolib/fileInfo.go:31
package hugolib
import (
"fmt"
"github.com/spf13/afero"
"github.com/gohugoio/hugo/source"
)
type fileInfo struct {
*source.File
}
func (fi *fileInfo) Open() (afero.File, error) {
f, err := fi.FileInfo().Meta().Open()
if err != nil {
err = fmt.Errorf("fileInfo: %w", err)
}
return f, err
}
func (fi *fileInfo) Lang() string {
return fi.File.Lang()
}
func (fi *fileInfo) String() string {
if fi == nil || fi.File == nil {
return ""
}
return fi.Path()
}
View on GitHub (pinned to 52c9bd7908)
Solutions
- Check the wrapped error (%w) — it names the real OS-level cause (ENOENT, EACCES, etc.) and the path.
- If running `hugo server`, re-save the file or confirm the file still exists on disk after editor operations.
- Verify filesystem permissions/ownership on the content directory and that the mount target paths in config exist.
- Remove or fix broken symlinks inside content/ and module mounts.
Example fix
// before: mount points to a removed dir [[mounts]] source = "content/posts/drafts" // deleted on disk // after: remove the stale mount or restore the directory [[mounts]] source = "content/posts"
Defensive patterns
Strategy: try-catch
Validate before calling
// Before opening, stat the file via the same afero fs to fail early:
if _, err := fi.FileInfo().Meta().Fs.Stat(path); err != nil {
return fmt.Errorf("pre-check stat failed: %w", err)
} Type guard
// Hugo is Go; treat any non-nil error from Open() as the signal.
// No type narrowing needed — callers should errors.Is/As the wrapped cause:
if errors.Is(err, fs.ErrNotExist) { /* handle missing file */ } Try / catch
f, err := fi.Open()
if err != nil {
var perr *fs.PathError
if errors.As(err, &perr) {
// I/O-level cause; log path and skip or fail the page
h.Log.Errorf("open %s: %v", perr.Path, perr)
return
}
return err
}
defer f.Close() Prevention
- Avoid mutating content files during an active build/watch; pause editing or re-save cleanly.
- Keep mounts pointing at stable, existing directories; validate mount sources at startup.
- Run builds with consistent file ownership/permissions in CI.
When it happens
Trigger: Produced when (fi *fileInfo).Open() is invoked and fi.FileInfo().Meta().Open() returns a non-nil error — typically because the backing afero filesystem cannot read the file (deleted, permissions, broken symlink, missing mount target).
Common situations: A content file is removed or renamed mid-build (common during `hugo server` watch while the editor saves/deletes); a content directory mount points at a path the process cannot read; a symlink loop or broken symlink inside content; permission errors after a chmod/chown in CI.
Related errors
- no existing content directory configured for this project
- failed to save file %q: %s
- data: failed to open %q: %w
- target path "{targetDir}" exists but is not a directory
- target path "{targetDir}" exists and is not empty
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/f1fe5b4ead7b0c94.
Report an issue: GitHub.