{"id":"da6bcdbc7c823605","repo":"gohugoio/hugo","slug":"openfunc-not-set","errorCode":null,"errorMessage":"OpenFunc not set","messagePattern":"OpenFunc not set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hugofs/fileinfo.go","lineNumber":131,"sourceCode":"\n\tfor i := range dstv.NumField() {\n\t\tv := dstv.Field(i)\n\t\tif !v.CanSet() {\n\t\t\tcontinue\n\t\t}\n\t\tif !hreflect.IsTruthfulValue(v) {\n\t\t\tv.Set(srcv.Field(i))\n\t\t}\n\t}\n\n\tif m.InclusionFilter == nil {\n\t\tm.InclusionFilter = from.InclusionFilter\n\t}\n}\n\nfunc (f *FileMeta) Open() (afero.File, error) {\n\tif f.OpenFunc == nil {\n\t\treturn nil, errors.New(\"OpenFunc not set\")\n\t}\n\treturn f.OpenFunc()\n}\n\nfunc (f *FileMeta) ReadAll() ([]byte, error) {\n\tfile, err := f.Open()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\treturn io.ReadAll(file)\n}\n\nfunc (f *FileMeta) JoinStat(name string) (FileMetaInfo, error) {\n\tif f.JoinStatFunc == nil {\n\t\treturn nil, os.ErrNotExist\n\t}\n\treturn f.JoinStatFunc(name)","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/hugofs/fileinfo.go#L113-L149","documentation":"`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.","triggerScenarios":"Calling FileMeta.Open() or FileMeta.ReadAll() on a FileMeta whose OpenFunc field is nil. ReadAll surfaces the same error since it calls Open first.","commonSituations":"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.","solutions":["Ensure the FileMeta is produced by the standard hugofs filesystem decorators, which set OpenFunc from the backing fs.","If constructing FileMeta manually, set OpenFunc to a closure opening the real file (e.g. func() (afero.File, error) { return fs.Open(path) }).","Check that the entry is actually a regular file, not a directory or synthetic node, before calling Open/ReadAll."],"exampleFix":"// before\nm := &hugofs.FileMeta{Filename: path}\nb, err := m.ReadAll() // OpenFunc not set\n// after\nm := &hugofs.FileMeta{Filename: path, OpenFunc: func() (afero.File, error) { return fs.Open(path) }}\nb, err := m.ReadAll()","handlingStrategy":"validation","validationCode":"// When constructing FileMeta manually, always set OpenFunc\nmeta := &hugofs.FileMeta{Filename: name, OpenFunc: func() (afero.File, error) { return fs.Open(name) }}\nif meta.OpenFunc == nil {\n    return fmt.Errorf(\"FileMeta for %s missing OpenFunc\", name)\n}","typeGuard":"func canOpen(fi hugofs.FileMetaInfo) bool {\n    return fi != nil && fi.Meta() != nil && fi.Meta().OpenFunc != nil\n}","tryCatchPattern":"f, err := fi.Meta().Open()\nif err != nil {\n    return fmt.Errorf(\"cannot open %s (was FileMeta built without OpenFunc?): %w\", fi.Meta().Filename, err)\n}\ndefer f.Close()","preventionTips":["Obtain FileMeta from Hugo's filesystem walkers rather than constructing it by hand","If you decorate or clone FileMeta, copy OpenFunc along with the other fields","Guard Meta().Open() call sites for synthetic/virtual files that have no backing content"],"tags":["filesystem","nil-check","hugo-internal"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}