{"record":{"id":"25dc8e4c94389f7c","repo":"gohugoio/hugo","slug":"failed-to-open-source-w","errorCode":null,"errorMessage":"failed to open source: %w","messagePattern":"failed to open source: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"resources/resource.go","lineNumber":675,"sourceCode":"\ntype isPublishedProvider interface {\n\tisPublished() bool\n}\n\ntype resourceHash struct {\n\tvalue    uint64\n\tsize     int64\n\tinitOnce sync.Once\n}\n\nfunc (r *resourceHash) init(l hugio.ReadSeekCloserProvider) error {\n\tvar initErr error\n\tr.initOnce.Do(func() {\n\t\tvar hash uint64\n\t\tvar size int64\n\t\tf, err := l.ReadSeekCloser()\n\t\tif err != nil {\n\t\t\tinitErr = fmt.Errorf(\"failed to open source: %w\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer f.Close()\n\t\thash, size, err = hashImage(f)\n\t\tif err != nil {\n\t\t\tinitErr = fmt.Errorf(\"failed to calculate hash: %w\", err)\n\t\t\treturn\n\t\t}\n\t\tr.value = hash\n\t\tr.size = size\n\t})\n\n\treturn initErr\n}\n\nfunc hashImage(r io.ReadSeeker) (uint64, int64, error) {\n\treturn hashing.XXHashFromReader(r)\n}","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/resources/resource.go#L657-L693","documentation":"Wrapped error from `resourceHash.init` (resource.go:668-689) when the underlying `ReadSeekCloser()` provider fails to open the resource's source bytes. Hugo needs the byte stream to compute the xxhash used as the resource identity/cache key. The error from `l.ReadSeekCloser()` at resource.go:673-675 is wrapped and returned once (guarded by `sync.Once`).","triggerScenarios":"Any code path that triggers lazy hash computation on a Resource whose source can't be opened: missing file on disk, broken symlink, remote resource whose body is already consumed/closed, page bundle path moved after registration, or a `ReadSeekCloser` factory returning an error.","commonSituations":"External process deleted a `static/` or `assets/` file between Hugo startup and hash computation; symlink to NAS dropped; concurrent `hugo mod` clean removing a module asset; custom resource provider returning an error from its opener; remote resource body closed before re-read.","solutions":["Verify the source file exists and is readable at the path Hugo resolved (`hugo config | grep resourceDir`, check perms).","For symlinks, confirm the target is intact and within the project root.","Re-run `hugo --gc` to clear stale cache entries that reference moved files.","For remote resources, ensure the body factory returns a fresh reader each call (don't reuse a consumed `io.Reader`).","If using a custom resource type, ensure its `ReadSeekCloser()` returns a non-nil error only on genuine I/O failure."],"exampleFix":"// custom resource provider -- before\nfunc (r *myRes) ReadSeekCloser() (hugio.ReadSeekCloser, error) {\n    return r.consumedReader, nil\n}\n\n// after\nfunc (r *myRes) ReadSeekCloser() (hugio.ReadSeekCloser, error) {\n    return hugio.NewReadSeekerNoOpCloser(bytes.NewReader(r.bytes)), nil\n}","handlingStrategy":"try-catch","validationCode":"// Before hashing, verify the source path exists.\nimport \"os\"\nfunc ensureReadable(p string) error {\n\tf, err := os.Open(p)\n\tif err != nil { return err }\n\tf.Close()\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"// Wrap resource creation; log and skip unopenable sources.\nr, err := rs.NewResource(...)\nif err != nil {\n\tif strings.Contains(err.Error(), \"failed to open source\") {\n\t\tlogger.Warnf(\"skip missing resource %s: %v\", path, err)\n\t\tcontinue\n\t}\n\treturn err\n}","preventionTips":["Run `hugo --gc` before builds to drop stale cache entries.","Keep `assets/`/`resources/` under version control or a stable mount.","For remote resources, ensure the body factory is re-openable."],"tags":["resources","io","hash","filesystem","cache"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}