{"record":{"id":"abd04a53442fc875","repo":"vi/websocat","slug":"nowhere-to-connect-it","errorCode":null,"errorMessage":"Nowhere to connect it","messagePattern":"Nowhere to connect it","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/util.rs","lineNumber":61,"sourceCode":"                }),\n            ), // This implementation (without Overlay{1,M} cases)\n               // causes task to be spawned too late (before establishing ws upgrade)\n               // when serving clients:\n\n               //ServeOnce(x) => ServeOnce(Box::new(x.and_then(f)) as BoxedNewPeerFuture),\n               //ServeMultipleTimes(s) => {\n               //    ServeMultipleTimes(Box::new(s.and_then(f)) as BoxedNewPeerStream)\n               //}\n        }\n    }\n\n    pub fn get_only_first_conn(self, l2r: L2rUser) -> BoxedNewPeerFuture {\n        use crate::PeerConstructor::*;\n        match self {\n            Error(e) => Box::new(futures::future::err(e)) as BoxedNewPeerFuture,\n            ServeMultipleTimes(stre) => Box::new(\n                stre.into_future()\n                    .map(move |(std_peer, _)| std_peer.expect(\"Nowhere to connect it\"))\n                    .map_err(|(e, _)| e),\n            ) as BoxedNewPeerFuture,\n            ServeOnce(futur) => futur,\n            Overlay1(futur, mapper) => {\n                Box::new(futur.and_then(move |p| mapper(p, l2r))) as BoxedNewPeerFuture\n            }\n            OverlayM(stre, mapper) => Box::new(\n                stre.into_future()\n                    .map(move |(std_peer, _)| std_peer.expect(\"Nowhere to connect it\"))\n                    .map_err(|(e, _)| e)\n                    .and_then(move |p| mapper(p, l2r)),\n            ) as BoxedNewPeerFuture,\n        }\n    }\n}\n\npub fn once(x: BoxedNewPeerFuture) -> PeerConstructor {\n    PeerConstructor::ServeOnce(x)","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/vi/websocat/blob/3a3574cd2f5d17857d87f3982e72c3ede159dde0/src/util.rs#L43-L79","documentation":"get_only_first_conn is for PeerConstructor variants expected to yield exactly one peer. For ServeMultipleTimes streams it takes the first item of the stream and unwraps it: None means the stream ended without producing any connection at all — there is 'nowhere to connect' the protocol handler — so the library panics instead of yielding a normal error.","triggerScenarios":"Using an option whose PeerConstructor is ServeMultipleTimes (a listening connector) in a single-connection context, when the listener produces zero connections before ending — e.g. the listen socket fails to yield a first client, an accept loop terminates immediately, or the underlying fd/pipe produces nothing.","commonSituations":"Pointing the program at a source that can accept but never receives a client (a named pipe, a unix socket no one connects to) combined with an option restricted to one connection; misusing connect-style logic on a serve-style option; the listener closing due to an early signal or error swallowed upstream.","solutions":["Use a connector option that produces a connection (ServeOnce) rather than a listener (ServeMultipleTimes) in this position","Check why the listener yields zero connections: verify the address/path, permissions, and that a client actually connects","Turn the expect into a proper error: map the None case to a failed future (e.g. io::Error::new(ErrorKind::BrokenPipe, 'no connection')) so the task ends with a diagnostic","If this is triggered programmatically, prefer get_only_first_conn only on constructors known to be ServeOnce/Overlay1"],"exampleFix":"// before\n.map(move |(std_peer, _)| std_peer.expect(\"Nowhere to connect it\"))\n// after\n.map(move |(std_peer, _)| std_peer.ok_or_else(|| {\n    io::Error::new(io::ErrorKind::BrokenPipe, \"no connection produced\")\n}))","handlingStrategy":"validation","validationCode":"// before relying on get_only_first_conn, ensure the constructor yields a connection\nif let PeerConstructor::ServeMultipleTimes(_) = ctor {\n    eprintln!(\"listener-style constructor: first connection may never arrive\");\n}","typeGuard":"fn yields_single_connection(c: &PeerConstructor) -> bool {\n    matches!(c, PeerConstructor::ServeOnce(_) | PeerConstructor::Overlay1(..))\n}","tryCatchPattern":"// panic in a future poll aborts the task; fence it\nlet res = std::panic::catch_unwind(AssertUnwindSafe(|| connect_first(&ctor)));","preventionTips":["Only call get_only_first_conn on constructors that produce exactly one peer","Verify listeners actually receive a client before relying on the first item","Check addresses, socket paths, and permissions so accept does not end with zero connections","Patch the library to convert None into a returned io error instead of panicking"],"tags":["panic","listener","connection","futures"],"backgroundTag":"empty-result-set","analyzedSha":"3a3574cd2f5d17857d87f3982e72c3ede159dde0","analyzedAt":"2026-09-12T15:14:27.766Z","contentChangedAt":"2026-09-12T15:14:27.766Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}