Kuberwastaken/claurst · error
connection closed while awaiting response to
Error message
connection closed while awaiting response to '{}' What it means
This error is thrown by the ACP connection's request/response correlator when the channel on which a pending response would arrive is dropped — i.e. the connection task shut down (or the connection was closed) before any response to the outstanding request arrived. The library uses a oneshot channel per in-flight request; `Err(_)` from `rx.await` means the sender half was dropped, so the response can never arrive.
Solutions
- Check that the ACP peer process is still running and inspect its stderr/logs for a crash or panic just before the error.
- Add a response timeout and reconnect logic: treat this error as 'connection lost', re-establish the connection, and resend the request.
- Ensure your code keeps the connection (and its background reader task) alive for the duration of awaited requests — do not drop the transport while requests are pending.
- Verify protocol/version compatibility: a peer that closes the socket on an unsupported method will surface as this error.
Example fix
// before
let resp = connection.send_request("session/prompt", params).await?;
// after
let resp = match connection.send_request("session/prompt", params).await {
Ok(r) => r,
Err(e) if e.to_string().contains("connection closed") => {
connection = reconnect().await?; // re-establish and retry once
connection.send_request("session/prompt", params).await??
}
Err(e) => return Err(e.into()),
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: check the connection is open before sending
if !connection.is_open() {
connection = reconnect().await?;
} Try / catch
// match on the send_request Result and treat 'connection closed' as reconnectable
match connection.send_request(method, params).await {
Ok(Ok(v)) => Ok(v),
Ok(Err(e)) => Err(e),
Err(e) if e.to_string().contains("connection closed") => reconnect_and_retry().await,
Err(e) => Err(e),
} Prevention
- Keep the connection/transport alive while requests are awaited; scope lifetimes accordingly.
- Implement a reconnect-with-retry wrapper around send_request.
- Monitor peer process health (exit events) to close sessions cleanly instead of letting awaits fail.
- Add a per-request timeout so hangs surface as timeouts, not silent closes.
When it happens
Trigger: Calling `connection.send_request(method, ...)` and the connection is closed/aborted while the request is still in flight: remote peer disconnected, the reader loop exited, or the connection object was dropped/shut down mid-request.
Common situations: An ACP agent/subprocess crashes or exits while the client awaits a tool or session response; a network drop between IDE and agent; shutting down the connection on timeout without cancelling in-flight requests; server restart during an active session.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
- models endpoint returned
- Bridge register: server returned
- start_bridge: bridge is not active
- Token exchange failed
- Token exchange failed
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/4c6ffcec8b59c7f8.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/acp/src/connection.rs:143
let params_value = serde_json::to_value(params)?;
let msg = serde_json::json!({
"jsonrpc": JSONRPC_VERSION,
"id": raw_id,
"method": method,
"params": params_value,
});
if let Err(e) = self.write_line(&msg).await {
self.pending.remove(&id_key);
return Err(e);
}
match rx.await {
Ok(Ok(value)) => {
let typed: R = serde_json::from_value(value)?;
Ok(Ok(typed))
}
Ok(Err(err)) => Ok(Err(err)),
Err(_) => Err(anyhow::anyhow!(
"connection closed while awaiting response to '{}'",
method
)),
}
}
async fn write_line(self: &Arc<Self>, value: &Value) -> anyhow::Result<()> {
let mut buf = serde_json::to_vec(value)?;
buf.push(b'\n');
let mut w = self.writer.lock().await;
w.write_all(&buf).await?;
w.flush().await?;
trace!(bytes = buf.len(), "ACP wire send");
Ok(())
}
/// Look up and resolve a pending outbound request when a response arrives.
fn complete_pending(&self, id: &acp::RequestId, payload: Result<Value, acp::Error>) {View on GitHub (pinned to b0637c97ec)