gohugoio/hugo · error

OpenFunc not set

Error message

OpenFunc not set

What it means

`FileMeta.Open` (hugofs/fileinfo.go:129) delegates to the OpenFunc closure attached when the FileMeta was constructed. If no OpenFunc was set — the metadata describes a file that has no readable backing (e.g. a synthetic or directory entry, or a FileMeta built without going through the normal decorator path) — Open fails fast with this error rather than returning a nil file.

Source

Thrown at hugofs/fileinfo.go:131

	for i := range dstv.NumField() {
		v := dstv.Field(i)
		if !v.CanSet() {
			continue
		}
		if !hreflect.IsTruthfulValue(v) {
			v.Set(srcv.Field(i))
		}
	}

	if m.InclusionFilter == nil {
		m.InclusionFilter = from.InclusionFilter
	}
}

func (f *FileMeta) Open() (afero.File, error) {
	if f.OpenFunc == nil {
		return nil, errors.New("OpenFunc not set")
	}
	return f.OpenFunc()
}

func (f *FileMeta) ReadAll() ([]byte, error) {
	file, err := f.Open()
	if err != nil {
		return nil, err
	}
	defer file.Close()
	return io.ReadAll(file)
}

func (f *FileMeta) JoinStat(name string) (FileMetaInfo, error) {
	if f.JoinStatFunc == nil {
		return nil, os.ErrNotExist
	}
	return f.JoinStatFunc(name)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Ensure the FileMeta is produced by the standard hugofs filesystem decorators, which set OpenFunc from the backing fs.
  2. If constructing FileMeta manually, set OpenFunc to a closure opening the real file (e.g. func() (afero.File, error) { return fs.Open(path) }).
  3. Check that the entry is actually a regular file, not a directory or synthetic node, before calling Open/ReadAll.

Example fix

// before
m := &hugofs.FileMeta{Filename: path}
b, err := m.ReadAll() // OpenFunc not set
// after
m := &hugofs.FileMeta{Filename: path, OpenFunc: func() (afero.File, error) { return fs.Open(path) }}
b, err := m.ReadAll()
Defensive patterns

Strategy: validation

Validate before calling

// When constructing FileMeta manually, always set OpenFunc
meta := &hugofs.FileMeta{Filename: name, OpenFunc: func() (afero.File, error) { return fs.Open(name) }}
if meta.OpenFunc == nil {
    return fmt.Errorf("FileMeta for %s missing OpenFunc", name)
}

Type guard

func canOpen(fi hugofs.FileMetaInfo) bool {
    return fi != nil && fi.Meta() != nil && fi.Meta().OpenFunc != nil
}

Try / catch

f, err := fi.Meta().Open()
if err != nil {
    return fmt.Errorf("cannot open %s (was FileMeta built without OpenFunc?): %w", fi.Meta().Filename, err)
}
defer f.Close()

Prevention

When it happens

Trigger: Calling FileMeta.Open() or FileMeta.ReadAll() on a FileMeta whose OpenFunc field is nil. ReadAll surfaces the same error since it calls Open first.

Common situations: Internal Hugo bug or custom code constructing FileMeta by hand instead of via hugofs decorators; merging FileMeta values where the source lacked an OpenFunc; treating a directory or virtual mount entry as a readable file.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/da6bcdbc7c823605.json. Report an issue: GitHub ↗.