zed-industries/zed · error
Failed to send sandbox fallback authorization: {error}
Error message
Failed to send sandbox fallback authorization: {error} What it means
When a sandboxed execution fails and the thread asks whether to retry or run unsandboxed, the fallback authorization is sent over the event stream; a failed unbounded_send means the receiver was dropped and this error wraps the send failure. The decision prompt cannot reach the user, so the fallback flow aborts.
Source
Thrown at crates/agent/src/thread.rs:6266
// failure reason): it's critical the user can see what
// they're approving to run unsandboxed. The reason is
// surfaced separately by the fallback details / warning.
tool_call: acp::ToolCallUpdate::new(
tool_call_id.clone(),
acp::ToolCallUpdateFields::new(),
)
.meta(
acp_thread::meta_with_sandbox_fallback_authorization(details),
),
options,
response: response_tx,
context: None,
kind: acp_thread::AuthorizationKind::ActionChoice,
},
)))
{
log::error!("Failed to send sandbox fallback authorization: {error}");
return Err(anyhow!(
"Failed to send sandbox fallback authorization: {error}"
));
}
let outcome = response_rx
.await
.map_err(|_| anyhow!("authorization channel closed"))?;
ensure_tool_call_authorization_not_interrupted(&outcome)?;
let option_id = outcome.option_id.0.as_ref();
if option_id == acp_thread::SANDBOX_FALLBACK_RETRY_OPTION_ID {
return Ok(SandboxFallbackDecision::Retry);
}
match acp_thread::SandboxPermission::from_id(option_id) {
Some(acp_thread::SandboxPermission::AllowOnce) => {
Ok(SandboxFallbackDecision::RunUnsandboxed)
}
Some(acp_thread::SandboxPermission::AllowThread) => {View on GitHub (pinned to bc538def45)
Solutions
- Keep the ThreadEvent receiver alive for the thread's whole lifetime, especially across error paths
- Treat the error as cancellation: stop the tool call and report the original sandbox failure
- Re-establish the session and rerun the tool if the user still wants it
- Cancel the thread before tearing down the client so pending prompts resolve
Defensive patterns
Strategy: try-catch
Try / catch
if let Err(err) = fallback_authorization_result {
if err.to_string().starts_with("Failed to send sandbox fallback authorization") {
// Event consumer is gone: fail the tool call with the original
// sandbox error instead of waiting for a decision.
return Err(original_sandbox_error);
}
return Err(err);
} Prevention
- Keep the ThreadEvent receiver alive across error paths, not only happy paths
- Treat send failures during fallback as cancellation and stop the tool call
- Cancel the thread before tearing down the client so pending prompts resolve
- Re-establish the session and rerun the tool if the user still wants it
When it happens
Trigger: The event-stream consumer disappears while a sandbox fallback decision (retry versus run unsandboxed) is pending: UI closed, session dropped, or client disconnected right after the sandbox error.
Common situations: Client teardown immediately after a sandbox failure; embedding code that drops the event receiver in error paths; reloads during fallback decisions.
Related errors
- Failed to send sandbox authorization: {error}
- Failed to send Windows-drive sandbox warning: {error}
- authorization channel closed
- Failed to send tool call decision prompt: {error}
- Permission to run tool denied by user
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/fb779b8dd7ed5840.
Report an issue: GitHub.