From 4a89623977be399535505c129b1f3c1f5e0ea772 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Fri, 6 Feb 2026 17:10:16 -0500 Subject: [PATCH] Handle authorization send errors instead of silently dropping with .ok() (#48639) The two `unbounded_send` calls in `ToolCallEventStream`'s authorize methods were using `.ok()` to silently discard send failures. This meant that if the authorization channel was closed, the tool call would hang indefinitely waiting for a response that would never come. ## Changes - Both `authorize_third_party_tool` and `authorize` methods now use `if let Err(error)` to detect send failures - On failure, logs the error with `log::error!` and returns `Task::ready(Err(...))` so callers get immediate, meaningful feedback Release Notes: - Tool authorization failures are now logged and reported instead of being silently ignored. --- crates/agent/src/thread.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/agent/src/thread.rs b/crates/agent/src/thread.rs index 7a97b4e05828452d674a307dd50d2689390e19ce..57aca268ed9eb43949c0a761cfb83aac34e7c91f 100644 --- a/crates/agent/src/thread.rs +++ b/crates/agent/src/thread.rs @@ -3128,7 +3128,8 @@ impl ToolCallEventStream { } let (response_tx, response_rx) = oneshot::channel(); - self.stream + if let Err(error) = self + .stream .0 .unbounded_send(Ok(ThreadEvent::ToolCallAuthorization( ToolCallAuthorization { @@ -3172,7 +3173,12 @@ impl ToolCallEventStream { context: None, }, ))) - .ok(); + { + log::error!("Failed to send tool call authorization: {error}"); + return Task::ready(Err(anyhow!( + "Failed to send tool call authorization: {error}" + ))); + } let fs = self.fs.clone(); cx.spawn(async move |cx| { @@ -3224,7 +3230,8 @@ impl ToolCallEventStream { let options = context.build_permission_options(); let (response_tx, response_rx) = oneshot::channel(); - self.stream + if let Err(error) = self + .stream .0 .unbounded_send(Ok(ThreadEvent::ToolCallAuthorization( ToolCallAuthorization { @@ -3237,7 +3244,12 @@ impl ToolCallEventStream { context: Some(context), }, ))) - .ok(); + { + log::error!("Failed to send tool call authorization: {error}"); + return Task::ready(Err(anyhow!( + "Failed to send tool call authorization: {error}" + ))); + } let fs = self.fs.clone(); cx.spawn(async move |cx| {