{"record":{"id":"67a94f884a4aa967","repo":"zed-industries/zed","slug":"is-not-a-directory","errorCode":null,"errorMessage":"{} is not a directory.","messagePattern":"(.+?) is not a directory\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/agent/src/tools/list_directory_tool.rs","lineNumber":311,"sourceCode":"                    anyhow::bail!(\n                        \"Cannot list directory because its path matches the user's worktree `file_scan_exclusions` setting: {}\",\n                        input.path\n                    );\n                }\n\n                if worktree_settings.is_path_private(&project_path.path) {\n                    anyhow::bail!(\n                        \"Cannot list directory because its path matches the user's worktree `private_paths` setting: {}\",\n                        input.path\n                    );\n                }\n\n                let worktree_snapshot = worktree.read(cx).snapshot();\n                let Some(entry) = worktree_snapshot.entry_for_path(&project_path.path) else {\n                    anyhow::bail!(\"Path not found: {}\", input.path);\n                };\n                if !entry.is_dir() {\n                    anyhow::bail!(\"{} is not a directory.\", input.path);\n                }\n\n                anyhow::Ok(())\n            }).map_err(|e| e.to_string())?;\n\n            if let Some(canonical_target) = &symlink_canonical_target {\n                let authorize = cx.update(|cx| {\n                    authorize_symlink_access(\n                        Self::NAME,\n                        &input.path,\n                        canonical_target,\n                        &event_stream,\n                        cx,\n                    )\n                });\n                authorize.await.map_err(|e| e.to_string())?;\n            }\n","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent/src/tools/list_directory_tool.rs#L293-L329","documentation":"list_directory found an entry for the path in the worktree snapshot, but entry.is_dir() is false — the path names a regular file (or symlink treated as a file), so it cannot be enumerated as a directory and the tool refuses.","triggerScenarios":"list_directory invoked on a regular file — e.g. asking to 'list' a file path, or a directory that was replaced by a file of the same name.","commonSituations":"The agent mistakes a file for a directory (e.g. `Cargo.toml` vs a `cargo/` folder); a file path is pasted where a directory was expected.","solutions":["Use the read_file tool on that path instead — it is a file","If a directory was expected, list the parent directory to find the correct folder name"],"exampleFix":"// before\nlist_directory(path=\"crates/foo/Cargo.toml\")\n\n// after\nread_file(path=\"crates/foo/Cargo.toml\")","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn is_listable_dir(project: &Project, project_path: &ProjectPath, cx: &App) -> bool {\n    project\n        .worktree_for_id(project_path.worktree_id, cx)\n        .and_then(|worktree| worktree.read(cx).snapshot().entry_for_path(&project_path.path).map(|e| e.is_dir()))\n        .unwrap_or(false)\n}","tryCatchPattern":"On 'is not a directory', route the same path to read_file instead of failing the user request.","preventionTips":["Check entry.is_dir() from the worktree snapshot before choosing list_directory vs read_file","Prefer listing the parent directory when unsure whether a path is a file or folder"],"tags":["agent","list-directory","not-a-directory","filesystem"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}