{"record":{"id":"2b4043b02de1ca62","repo":"zed-industries/zed","slug":"cannot-capture-writable-sandbox-path","errorCode":null,"errorMessage":"cannot capture writable sandbox path `{}`","messagePattern":"cannot capture writable sandbox path `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/acp_thread/src/terminal.rs","lineNumber":279,"sourceCode":"    /// synthesized `settings.json/.git` routes through a file — without closing\n    /// the hole. So we drop and move on.\n    fn to_policy(&self) -> Result<sandbox::SandboxPolicy> {\n        let protected_paths = self\n            .protected_paths\n            .iter()\n            .filter_map(|path| sandbox::HostFilesystemLocation::capture(path).ok())\n            .collect::<Vec<_>>();\n        let fs = if self.allow_fs_write {\n            sandbox::SandboxFsPolicy::Unrestricted { protected_paths }\n        } else {\n            // Project worktree paths are captured fresh; user-approved grants are\n            // rebuilt via the verifying reopen (or captured when legacy bare\n            // strings) through `granted_write_path_to_location`. A path that\n            // can't be captured fails the whole construction (never created).\n            let mut locations = Vec::new();\n            for path in &self.writable_paths {\n                let location = sandbox::HostFilesystemLocation::capture(path).map_err(|error| {\n                    anyhow::anyhow!(error).context(format!(\n                        \"cannot capture writable sandbox path `{}`\",\n                        path.display()\n                    ))\n                })?;\n                locations.push(location);\n            }\n            for granted in &self.extra_write_paths {\n                let location = granted_write_path_to_location(granted).map_err(|error| {\n                    anyhow::anyhow!(error).context(format!(\n                        \"cannot re-verify approved sandbox write grant `{}` (if the \\\n                         directory was removed, remove the grant or recreate the \\\n                         directory)\",\n                        granted.requested.display()\n                    ))\n                })?;\n                locations.push(location);\n            }\n            // Dedupe to a minimal cover on the captured canonical paths, so a","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/acp_thread/src/terminal.rs#L261-L297","documentation":"When building the sandbox fs policy (allow_fs_write == false), every worktree path in writable_paths is re-captured via sandbox::HostFilesystemLocation::capture; a capture failure wraps the error with this context and fails the whole terminal construction. The design is fail-closed: a writable path that cannot be captured is never silently dropped from the sandbox.","triggerScenarios":"A directory listed in writable_paths no longer exists (deleted, renamed, unmounted) or is unreadable at terminal-spawn time — e.g. the worktree was removed externally while the project stayed open.","commonSituations":"User deletes a multiworktree folder with the agent panel open; git prunes a worktree; permissions on the directory changed; a removable/FUSE mount holding the worktree went away.","solutions":["Recreate the missing directory named in the error, or re-open the project so the worktree list refreshes","Remove the stale worktree from the project before spawning further agent terminals","Fix directory permissions if the path exists but cannot be captured"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify every writable path still exists before spawning the terminal\nlet missing: Vec<_> = writable_paths.iter()\n    .filter(|path| !path.exists())\n    .cloned()\n    .collect();\nif !missing.is_empty() {\n    return notify_user(format!(\"worktree paths no longer exist: {missing:?}\"));\n}","typeGuard":"fn all_writable_paths_exist(paths: &[Arc<Path>]) -> bool {\n    paths.iter().all(|path| path.is_dir())\n}","tryCatchPattern":null,"preventionTips":["Re-validate worktree paths when the project regains focus; stale lists are the usual cause","Remove deleted worktrees from the project instead of leaving them registered","Surface the exact path from the error message — it names the offender"],"tags":["rust","zed","sandbox","filesystem","terminal","worktree"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}