{"record":{"id":"c4f7e1962344f010","repo":"charmbracelet/crush","slug":"failed-to-crawl-for-stats-w","errorCode":null,"errorMessage":"failed to crawl for stats: %w","messagePattern":"failed to crawl for stats: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/stats.go","lineNumber":151,"sourceCode":"type ProjectStats struct {\n\tProjectPath string `json:\"project_path\"`\n\tStats       *Stats `json:\"stats\"`\n}\n\nfunc runStats(cmd *cobra.Command, _ []string) error {\n\tctx := cmd.Context()\n\tdataDir, _ := cmd.Flags().GetString(\"data-dir\")\n\tcrawlDir, _ := cmd.Flags().GetString(\"crawl-dir\")\n\tuseAll, _ := cmd.Flags().GetBool(\"all\")\n\n\tvar projectStats []ProjectStats\n\tvar err error\n\n\tswitch {\n\tcase crawlDir != \"\":\n\t\tprojectStats, err = crawlForStats(ctx, crawlDir)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to crawl for stats: %w\", err)\n\t\t}\n\tcase useAll:\n\t\tprojectStats, err = gatherStatsFromProjects(ctx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to gather stats from projects: %w\", err)\n\t\t}\n\tdefault:\n\t\tcfg, err := config.Init(\"\", dataDir, false)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to initialize config: %w\", err)\n\t\t}\n\t\tif dataDir == \"\" {\n\t\t\tdataDir = cfg.Config().Options.DataDirectory\n\t\t}\n\t\tif shouldEnableMetrics(cfg.Config()) {\n\t\t\tevent.Init()\n\t\t}\n","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/cmd/stats.go#L133-L169","documentation":"`crush stats --crawl-dir <dir>` walks the given directory tree to compute project statistics via `crawlForStats`. This error wraps any failure of that crawl — unreadable directories, permission errors, or internal crawl failures — as `failed to crawl for stats: <cause>`. The actionable detail is always in the wrapped cause.","triggerScenarios":"Running `crush stats` with a non-empty `--crawl-dir` flag where `crawlForStats(ctx, crawlDir)` at internal/cmd/stats.go:149 returns an error: the directory does not exist, is not readable, or the walker hits an unrecoverable I/O error while traversing.","commonSituations":"Typo in the --crawl-dir path; pointing at a file instead of a directory; crawling a directory with restricted permissions (e.g. another user's home); crawling a network mount that drops mid-scan.","solutions":["Read the wrapped cause after the colon to see which path/operation failed.","Verify the --crawl-dir path exists and is a directory: `ls -ld <dir>`.","Check read/execute permissions on the directory tree (`find <dir> -not -readable`).","Re-run pointing at a valid, accessible directory, or omit --crawl-dir to use the default local data directory."],"exampleFix":"// before\ncrush stats --crawl-dir ./projct  # typo\n// after\ncrush stats --crawl-dir ./project","handlingStrategy":"validation","validationCode":"dir := \"./project\"\ninfo, err := os.Stat(dir)\nif err != nil || !info.IsDir() {\n    log.Fatalf(\"--crawl-dir %s is not an existing directory\", dir)\n}\nif f, err := os.Open(dir); err != nil {\n    log.Fatalf(\"--crawl-dir %s not readable: %v\", dir, err)\n} else {\n    f.Close()\n}","typeGuard":"func isCrawlableDir(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && info.IsDir()\n}","tryCatchPattern":"out, err := exec.Command(\"crush\", \"stats\", \"--crawl-dir\", dir).CombinedOutput()\nif err != nil {\n    if strings.Contains(string(out), \"failed to crawl for stats\") {\n        log.Fatalf(\"crawl failed for %s: %s\", dir, out)\n    }\n    log.Fatalf(\"stats failed: %v: %s\", err, out)\n}","preventionTips":["Verify the --crawl-dir path exists and is a directory before invoking.","Use absolute paths to avoid cwd-related typos.","Check permissions across the tree when crawling shared or system directories.","Avoid crawling network mounts that can drop mid-scan; copy locally first if needed."],"tags":["stats","filesystem","crawl","cli"],"backgroundTag":"path-not-found","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}