gohugoio/hugo · error

failed to open file %q: %w

Error message

failed to open file %q: %w

What it means

From HugoSites.newPageMetaSourceFromFile's openSource closure (page__meta.go:342). It calls meta.Open() to obtain a reader for a content source file; if the OS/hugo filesystem returns an error (file vanished, permission denied, I/O error) it is wrapped with the filename so the offending file is identifiable.

Source

Thrown at hugolib/page__meta.go:342

		}
		m.singular = tc.singular

		if m.pageConfigSource.Kind == kinds.KindTerm {
			m.term = paths.TrimLeading(strings.TrimPrefix(m.pathInfo.Unnormalized().Base(), "/"+tc.plural))
		}
	}

	return nil
}

// bookmark1
func (h *HugoSites) newPageMetaSourceFromFile(fi hugofs.FileMetaInfo) (*pageMetaSource, error) {
	p, err := func() (*pageMetaSource, error) {
		meta := fi.Meta()
		openSource := func() (hugio.ReadSeekCloser, error) {
			r, err := meta.Open()
			if err != nil {
				return nil, fmt.Errorf("failed to open file %q: %w", meta.Filename, err)
			}
			return r, nil
		}

		p := &pageMetaSource{
			f:          source.NewFileInfo(fi),
			pathInfo:   fi.Meta().PathInfo,
			openSource: openSource,
		}

		return p, nil
	}()
	if err != nil {
		return nil, hugofs.AddFileInfoToError(err, fi, h.SourceFs)
	}

	return p, err
}

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Confirm the file exists and is readable at the reported path.
  2. On watch, trigger another rebuild after the editor has finished saving.
  3. Fix permissions/ownership of the content tree.
  4. Disable any process locking the content files (antivirus, sync clients).
Defensive patterns

Strategy: retry

Validate before calling

// library/watch use: tolerate transient open failures and re-run the build
// if isTransientOpenErr(err) { rebuildOnce() }

Try / catch

if errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrPermission) {
    // file vanished mid-save or unreadable: retry / fix perms
}

Prevention

When it happens

Trigger: A content file that was present during enumeration is gone or unreadable when Hugo opens it — typical on watch rebuilds where an editor does an atomic save/replace, or when permissions/ownership block the read. The underlying %w is the fs error (ENOENT, EACCES).

Common situations: Editor atomic-save race during `hugo server`; file moved/deleted between discovery and open; container/CI filesystem permission mismatch; antivirus/locking on Windows.

Related errors


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