{"record":{"id":"70a8f9aa5ca8b0f1","repo":"gastownhall/beads","slug":"walk-returned-no-file-information-for-s","errorCode":null,"errorMessage":"walk returned no file information for %s","messagePattern":"walk returned no file information for (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/directory_size.go","lineNumber":51,"sourceCode":"\t}\n\n\treturn measureDirectorySizeWithWalk(ctx, resolvedRoot, filepath.Walk)\n}\n\nfunc measureDirectorySizeWithWalk(ctx context.Context, root string, walk directoryWalkFunc) (int64, error) {\n\tvar size int64\n\terr := walk(root, func(path string, info os.FileInfo, walkErr error) error {\n\t\tif err := ctx.Err(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif walkErr != nil {\n\t\t\tif path != root && errors.Is(walkErr, fs.ErrNotExist) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn walkErr\n\t\t}\n\t\tif info == nil {\n\t\t\treturn fmt.Errorf(\"walk returned no file information for %s\", path)\n\t\t}\n\t\tif info.IsDir() {\n\t\t\treturn nil\n\t\t}\n\t\tif info.Size() < 0 || info.Size() > math.MaxInt64-size {\n\t\t\treturn fmt.Errorf(\"directory size overflows int64 at %s\", path)\n\t\t}\n\t\tsize += info.Size()\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn size, nil\n}\n","sourceCodeStart":33,"sourceCodeEnd":67,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/directory_size.go#L33-L67","documentation":"MeasureDirectorySize walks a directory tree summing file sizes via filepath.Walk. The walk callback guards against a nil os.FileInfo, which the walk contract should never produce when no walkErr is set. This error means the walker received a nil info for a path without an accompanying error — an unexpected internal/filesystem inconsistency, so it is surfaced instead of silently counting the entry as zero bytes.","triggerScenarios":"During MeasureDirectorySize, filepath.Walk invokes the callback with path having a nil os.FileInfo and a nil walkErr — a state outside the documented Walk contract, typically only reachable with a custom walk function injected via measureDirectorySizeWithWalk or exotic filesystem behavior.","commonSituations":"Custom/dummy walk implementations passed in tests that call the callback with (path, nil, nil); filesystem layers (FUSE, network mounts) that misreport FileInfo; regressions in the walk function itself.","solutions":["Inspect the custom walk function passed to measureDirectorySizeWithWalk; ensure it never invokes the callback with a nil FileInfo and nil error.","Stat the reported path manually (os.Stat/os.Lstat) to check whether the filesystem is returning valid metadata for that entry.","If a network/FUSE/overlay filesystem is involved, retry the measurement or check the mount health, since metadata can transiently fail to resolve.","If the path is genuinely gone mid-walk, re-run MeasureDirectorySize; the normal race path (walkErr=fs.ErrNotExist) is tolerated, so only broken metadata triggers this."],"exampleFix":"// before: custom walk calls cb(path, nil, nil) for skipped entries\ncb(path, nil, nil)\n// after: skip the callback entirely or pass an error\ncb(path, nil, fs.ErrNotExist) // tolerated by the size walker for non-root paths","handlingStrategy":"type-guard","validationCode":"if info, err := os.Stat(root); err != nil || !info.IsDir() {\n    return fmt.Errorf(\"root %s is not a statable directory: %w\", root, err)\n}","typeGuard":"func validWalkEntry(path string, info os.FileInfo, err error) bool {\n    return err == nil && info != nil\n}","tryCatchPattern":"size, err := storage.MeasureDirectorySize(ctx, root)\nif err != nil {\n    if strings.Contains(err.Error(), \"walk returned no file information\") {\n        // invariant violation: re-run once or log and fall back to du-style estimate\n    }\n    return err\n}","preventionTips":["Only pass the standard filepath.Walk (or a walk implementation honoring the Walk contract) to measureDirectorySizeWithWalk.","In test doubles for the walk function, never call the callback with (nil, nil) — use fs.ErrNotExist to signal skipped entries.","Treat this error as a bug report trigger, not a user-facing condition; include the path in logs."],"tags":["filesystem","go","walk","invariant-violation"],"backgroundTag":"walk-returned-no-fileinfo","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}