{"record":{"id":"567e5469ac95d9fe","repo":"zed-industries/zed","slug":"project-entry-not-found","errorCode":null,"errorMessage":"project entry not found","messagePattern":"project entry not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/agent_ui/src/mention_set.rs","lineNumber":1255,"sourceCode":"                        .to_string_lossy()\n                        .to_string(),\n                ));\n            }\n        }\n\n        files\n    }\n\n    let Some(project_path) = project\n        .read(cx)\n        .project_path_for_absolute_path(&abs_path, cx)\n    else {\n        return Task::ready(Err(anyhow!(\n            \"project path not found for directory mention {abs_path:?}\"\n        )));\n    };\n    let Some(entry) = project.read(cx).entry_for_path(&project_path, cx) else {\n        return Task::ready(Err(anyhow!(\"project entry not found\")));\n    };\n    let directory_path = entry.path.clone();\n    let worktree_id = project_path.worktree_id;\n    let Some(worktree) = project.read(cx).worktree_for_id(worktree_id, cx) else {\n        return Task::ready(Err(anyhow!(\"worktree not found\")));\n    };\n    let project = project.clone();\n    cx.spawn(async move |cx| {\n        let file_paths = worktree.read_with(cx, |worktree, _cx| {\n            collect_files_in_path(worktree, &directory_path)\n        });\n        let descendants_future = cx.update(|cx| {\n            futures::future::join_all(file_paths.into_iter().map(\n                |(worktree_path, full_path): (Arc<RelPath>, String)| {\n                    let rel_path = worktree_path\n                        .strip_prefix(&directory_path)\n                        .map_or_else(|_| worktree_path.clone(), |rel_path| rel_path.into());\n","sourceCodeStart":1237,"sourceCodeEnd":1273,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent_ui/src/mention_set.rs#L1237-L1273","documentation":"After resolving the directory's ProjectPath, the flow looks the entry up in the worktree snapshot via project.entry_for_path. None means the snapshot has no entry for that path yet — the background scan has not reached that subtree, the entry was deleted, or the path does not resolve to a snapshot entry (casing or unicode normalization mismatch).","triggerScenarios":"Mentioning a directory in a freshly opened large worktree before the background scan populates that subtree; the directory being deleted between picker population and confirmation; NFC/case path differences on macOS or case-insensitive filesystems.","commonSituations":"Large monorepos immediately after opening; directories removed by a clean/build task while the picker is open; paths that differ only in normalization from the snapshot entry.","solutions":["Wait for the worktree scan to finish (the project tree shows the directory) and retry.","Verify the directory still exists on disk.","Reopen or refresh the worktree if the snapshot appears stale."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let entry_in_snapshot = project\n    .read(cx)\n    .entry_for_path(&project_path, cx)\n    .is_some();\nif !entry_in_snapshot {\n    // wait for the worktree scan to complete before offering the directory\n}","typeGuard":null,"tryCatchPattern":"match confirm_task.await {\n    Ok(mention) => { /* attach */ }\n    Err(err) if err.to_string() == \"project entry not found\" => {\n        show_user(\"Directory is not in the project snapshot yet; try again after scanning finishes\")\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Only list directories that already appear in the worktree snapshot.","Subscribe to worktree scan-complete events and refresh the picker.","Canonicalize paths (case and unicode form) before lookup."],"tags":["zed","worktree","snapshot","fs-scan","mentions"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}