{"record":{"id":"fa3ceeb22134f263","repo":"spacedriveapp/spacedrive","slug":"failed-to-open-bidirectional-stream-fa3cee","errorCode":null,"errorMessage":"Failed to open bidirectional stream: {}","messagePattern":"Failed to open bidirectional stream: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"core/src/service/network/protocol/sync/transport.rs","lineNumber":160,"sourceCode":"\t\t\t.as_ref()\n\t\t\t.ok_or_else(|| anyhow::anyhow!(\"Network endpoint not initialized\"))?;\n\n\t\t// Connect with SYNC_ALPN\n\t\tlet conn = endpoint.connect(node_id.into(), SYNC_ALPN).await.map_err(|e| {\n\t\t\twarn!(\n\t\t\t\tdevice_uuid = %target_device,\n\t\t\t\tnode_id = %node_id,\n\t\t\t\terror = %e,\n\t\t\t\t\"Failed to connect to device for sync request\"\n\t\t\t);\n\t\t\tanyhow::anyhow!(\"Failed to connect to {}: {}\", target_device, e)\n\t\t})?;\n\n\t\t// Open bidirectional stream\n\t\tlet (mut send, mut recv) = conn\n\t\t\t.open_bi()\n\t\t\t.await\n\t\t\t.map_err(|e| anyhow::anyhow!(\"Failed to open bidirectional stream: {}\", e))?;\n\n\t\t// Serialize and send request\n\t\tlet req_bytes = serde_json::to_vec(&request)\n\t\t\t.map_err(|e| anyhow::anyhow!(\"Failed to serialize sync request: {}\", e))?;\n\n\t\tlet len = req_bytes.len() as u32;\n\t\tsend.write_all(&len.to_be_bytes())\n\t\t\t.await\n\t\t\t.map_err(|e| anyhow::anyhow!(\"Failed to send length: {}\", e))?;\n\t\tsend.write_all(&req_bytes)\n\t\t\t.await\n\t\t\t.map_err(|e| anyhow::anyhow!(\"Failed to send request: {}\", e))?;\n\n\t\t// Properly close send stream\n\t\tsend.finish()\n\t\t\t.map_err(|e| anyhow::anyhow!(\"Failed to finish stream: {}\", e))?;\n\n\t\tdebug!(\"Sync request sent, waiting for response...\");","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/service/network/protocol/sync/transport.rs#L142-L178","documentation":"After a successful connect, conn.open_bi() failed in send_sync_request. On a QUIC connection this happens when the connection is lost or stopped between connect and stream creation, when the peer's bidirectional stream limit is exhausted, or when the peer's accept loop has stopped (crashed or shutting down).","triggerScenarios":"Peer disconnected immediately after the handshake; peer sync accept task panicked or exited; concurrent sync requests exhausting the peer's remote bidirectional stream limit; idle timeout firing during open_bi.","commonSituations":"Peer app being closed while a sync cycle runs; fan-out sync hammering one device with many concurrent requests; peer daemon crash-looping.","solutions":["Drop the connection and retry the request once on a fresh connection","Check the peer's logs for a crashed or exited sync accept loop","Bound the number of concurrent in-flight sync requests per peer","Confirm the peer accepts bidirectional streams for SYNC_ALPN"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match net.send_sync_request(device, request.clone()).await {\n    Ok(resp) => { /* ... */ }\n    Err(e) if e.to_string().contains(\"Failed to open bidirectional stream\") => {\n        // connection-level failure: drop conn, reconnect once, retry\n        retry_once_with_fresh_connection(device, request).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Bound concurrent sync requests per peer to avoid stream-limit exhaustion","Monitor peer accept-loop health; a crashed handler turns every open_bi into this error","Treat connect and open_bi failures identically: reconnect and retry once"],"tags":["network","iroh","quic","streams","sync","rust"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}