{"record":{"id":"3eece7d7b78bb68d","repo":"sinelaw/fresh","slug":"invalidinput","errorCode":"InvalidInput","errorMessage":"Path is not a directory: {:?}","messagePattern":"Path is not a directory: (.+?)","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/view/file_tree/tree.rs","lineNumber":46,"sourceCode":"}\n\nimpl FileTree {\n    /// Create a new file tree rooted at the given path\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the root path doesn't exist or isn't a directory.\n    pub async fn new(root_path: PathBuf, fs_manager: Arc<FsManager>) -> io::Result<Self> {\n        // Verify root path exists and is a directory\n        if !fs_manager.exists(&root_path).await {\n            return Err(io::Error::new(\n                io::ErrorKind::NotFound,\n                format!(\"Path does not exist: {:?}\", root_path),\n            ));\n        }\n\n        if !fs_manager.is_dir(&root_path).await? {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidInput,\n                format!(\"Path is not a directory: {:?}\", root_path),\n            ));\n        }\n\n        // Get root entry\n        let root_entry = fs_manager.get_entry(&root_path).await?;\n\n        // Create root node\n        let root_id = NodeId(0);\n        let root_node = TreeNode::new(root_id, root_entry.clone(), None);\n\n        let mut nodes = HashMap::new();\n        nodes.insert(root_id, root_node);\n\n        let mut path_to_node = HashMap::new();\n        path_to_node.insert(root_path.clone(), root_id);\n","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/view/file_tree/tree.rs#L28-L64","documentation":"After confirming the root exists, `FileTree::new` checks that it is a directory; a plain file (or other non-directory) yields `io::ErrorKind::InvalidInput` with \"Path is not a directory\". The tree can only be rooted at directories.","triggerScenarios":"Calling `FileTree::new` with a path that exists but `fs_manager.is_dir()` reports false — most commonly passing a file path as the tree root.","commonSituations":"Users selecting a file instead of a folder in an open dialog; config pointing at a single file; scripts passing a filename where a directory is expected.","solutions":["Pass a directory path as the root, not a file","Validate `is_dir` before constructing and route file paths to a file-open flow instead","If a file was selected, root the tree at its parent directory"],"exampleFix":"// before\nlet tree = FileTree::new(path, fs.clone()).await?;\n// after\nlet root = if fs.is_dir(&path).await? { path } else { path.parent().unwrap().to_path_buf() };\nlet tree = FileTree::new(root, fs.clone()).await?;","handlingStrategy":"validation","validationCode":"if std::path::Path::new(&root_path).is_file() {\n    let root_path = root_path.parent().unwrap().to_path_buf();\n}","typeGuard":null,"tryCatchPattern":"match FileTree::new(root_path, fs).await {\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput => eprintln!(\"{} is not a directory\", root_path.display()),\n    other => other?,\n}","preventionTips":["Only pass directories from file pickers (set the dialog to select directories)","Route file selections to the editor's open-file flow","Check is_dir before building trees","Normalize and validate configured workspace paths"],"tags":["io","filesystem","invalid-input"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}