{"record":{"id":"3488bddf0de68f27","repo":"sigoden/aichat","slug":"not-found","errorCode":null,"errorMessage":"Not found '{}'","messagePattern":"Not found '(.+?)'","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/utils/path.rs","lineNumber":164,"sourceCode":"        Ok((base_path, extensions, current_only))\n    } else if path_str.ends_with(\"/**\") || path_str.ends_with(r\"\\**\") {\n        Ok((path_str[0..path_str.len() - 3].to_string(), None, false))\n    } else {\n        Ok((path_str.to_string(), None, false))\n    }\n}\n\n#[async_recursion::async_recursion]\nasync fn list_files(\n    files: &mut IndexSet<String>,\n    entry_path: &Path,\n    suffixes: Option<&Vec<String>>,\n    current_only: bool,\n    bail_non_exist: bool,\n) -> Result<()> {\n    if !entry_path.exists() {\n        if bail_non_exist {\n            bail!(\"Not found '{}'\", entry_path.display());\n        } else {\n            return Ok(());\n        }\n    }\n    if entry_path.is_dir() {\n        let mut reader = tokio::fs::read_dir(entry_path).await?;\n        while let Some(entry) = reader.next_entry().await? {\n            let path = entry.path();\n            if path.is_dir() {\n                if !current_only {\n                    list_files(files, &path, suffixes, current_only, bail_non_exist).await?;\n                }\n            } else {\n                add_file(files, suffixes, &path);\n            }\n        }\n    } else {\n        add_file(files, suffixes, entry_path);","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/utils/path.rs#L146-L182","documentation":"list_files walks a path (recursively when called from expand_glob_paths) and bails with \"Not found '<path>'\" when the entry does not exist and bail_non_exist is true. It is a strict-existence check so glob expansion fails fast on missing roots.","triggerScenarios":"Expanding glob patterns whose base directory doesn't exist, or a config including a file path that was deleted/renamed, with the bail-on-missing option enabled.","commonSituations":"Typos in configured include paths; repository layout changed after config was written; running from a different working directory than the config assumes; case-sensitivity mismatches on Linux.","solutions":["Verify the path in the message exists relative to the working directory","Fix the typo or update the config path after renaming/moving files","Remove stale entries pointing at deleted files","Use an absolute path or adjust the base directory if CWD differs"],"exampleFix":"// before\ninclude = [\"srcs/**/*.rs\"]  // typo: no 'srcs' dir\n// after\ninclude = [\"src/**/*.rs\"]","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nfunction assertPathsExist(paths) {\n  for (const p of paths) {\n    if (!fs.existsSync(p.split('*')[0].replace(/[^/]*$/, '') || '.')) {\n      throw new Error(`base path missing for ${p}`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use paths relative to the repo root and run from there","Update config when files are moved or deleted","Watch out for case-sensitive filesystems"],"tags":["filesystem","path","glob","not-found"],"backgroundTag":"file-not-found","analyzedSha":"82976d349ad97ac9aae0655ad631dace5e2a6385","analyzedAt":"2026-09-09T18:33:06.139Z","contentChangedAt":"2026-09-09T18:33:06.139Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}