{"record":{"id":"eaafbf4377c51bf3","repo":"zed-industries/zed","slug":"permission-to-run-tool-denied-by-user","errorCode":null,"errorMessage":"Permission to run tool denied by user","messagePattern":"Permission to run tool denied by user","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/agent/src/thread.rs","lineNumber":6042,"sourceCode":"    ) -> Result<()> {\n        debug_assert!(\n            outcome.params.is_none(),\n            \"unexpected params for sandbox permission\"\n        );\n\n        match acp_thread::SandboxPermission::from_id(outcome.option_id.0.as_ref()) {\n            Some(acp_thread::SandboxPermission::AllowOnce) => Ok(()),\n            Some(acp_thread::SandboxPermission::AllowThread) => {\n                sandbox_grants.borrow_mut().record(request);\n                Self::persist_thread_grants(&thread, cx);\n                Ok(())\n            }\n            Some(acp_thread::SandboxPermission::AllowAlways) => {\n                Self::persist_sandbox_always_permission(request, fs, cx);\n                Ok(())\n            }\n            Some(acp_thread::SandboxPermission::Deny) => {\n                Err(anyhow!(\"Permission to run tool denied by user\"))\n            }\n            None => {\n                let other = outcome.option_id.0.as_ref();\n                debug_assert!(false, \"unexpected sandbox permission option_id: {other}\");\n                Err(anyhow!(\"Permission to run tool denied by user\"))\n            }\n        }\n    }\n\n    fn persist_sandbox_always_permission(\n        request: &SandboxRequest,\n        fs: Option<Arc<dyn Fs>>,\n        cx: &AsyncApp,\n    ) {\n        let Some(fs) = fs else {\n            log::error!(\n                \"Cannot persist \\\"allow always\\\" sandbox permission: no filesystem available\"\n            );","sourceCodeStart":6024,"sourceCodeEnd":6060,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent/src/thread.rs#L6024-L6060","documentation":"When a sandbox permission prompt resolves to Deny, the tool call fails with this error. It is the expected control flow for user refusal: the sandboxed request is not executed and no grant is recorded, unlike AllowThread and AllowAlways which persist permission.","triggerScenarios":"The user selects the Deny option on a sandbox authorization request for a tool call, so handle_sandbox_permission_outcome returns Err.","commonSituations":"Users declining commands whose sandbox request looks too broad; review or pairing flows where a reviewer denies an action; automated policies that answer prompts with Deny.","solutions":["Surface 'denied by user' in the transcript and continue the conversation; do not retry automatically","If the denial blocks legitimate work, narrow the tool invocation or adjust sandbox settings so the request is more specific","Let the user rerun the tool if they change their mind","Treat it as expected control flow, not as a bug or failure metric"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match sandbox_permission_outcome {\n    Ok(()) => run_sandboxed_request(),\n    Err(err) if err.to_string() == \"Permission to run tool denied by user\" => {\n        // Expected denial: report and continue the conversation.\n        report_to_user(\"Tool call denied\");\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Treat user denials as expected control flow, not as errors to suppress or retry","Narrow tool invocations so sandbox requests look specific and trustworthy","Let users rerun a denied tool instead of retrying it automatically","Record denials in the transcript; do not count them as failures in health metrics"],"tags":["rust","agent","sandbox","authorization","user-denial"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}