{"record":{"id":"ee72c5859f8430b6","repo":"LGUG2Z/komorebi","slug":"stream-should-be-cloneable","errorCode":null,"errorMessage":"stream should be cloneable","messagePattern":"stream should be cloneable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"komorebi/src/process_command.rs","lineNumber":168,"sourceCode":"\n    std::thread::spawn(move || {\n        tracing::info!(\"listening on 0.0.0.0:43663\");\n        for client in listener.incoming() {\n            match client {\n                Ok(mut stream) => {\n                    net2::TcpStreamExt::set_keepalive(&stream, Some(Duration::from_secs(30)))\n                        .expect(\"TCP keepalive should be set\");\n\n                    let addr = stream\n                        .peer_addr()\n                        .expect(\"incoming connection should have an address\")\n                        .to_string();\n\n                    let mut connections = TCP_CONNECTIONS.lock();\n\n                    connections.insert(\n                        addr.clone(),\n                        stream.try_clone().expect(\"stream should be cloneable\"),\n                    );\n\n                    tracing::info!(\"listening for incoming tcp messages from {}\", &addr);\n\n                    match read_commands_tcp(&wm, &mut stream, &addr) {\n                        Ok(()) => {}\n                        Err(error) => tracing::error!(\"{}\", error),\n                    }\n                }\n                Err(error) => {\n                    tracing::error!(\"{}\", error);\n                    break;\n                }\n            }\n        }\n    });\n}\n","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/LGUG2Z/komorebi/blob/e0709f02bfae4e503bf4640f58ee75ecbbfdbb97/komorebi/src/process_command.rs#L150-L186","documentation":"After accepting a TCP client, komorebi clones the stream via try_clone() so it can both write responses and read commands, panicking with 'stream should be cloneable' on failure. try_clone fails only at the OS level (e.g. descriptor/resource exhaustion or unsupported socket type).","triggerScenarios":"stream.try_clone() returns Err while registering an accepted connection in TCP_CONNECTIONS — practically only under handle/fd exhaustion or on exotic platforms.","commonSituations":"System running out of file/socket handles after many connections; resource limits hit during long-running sessions.","solutions":["Check for socket/handle leaks in the system (close idle connections to komorebi)","Raise the per-process handle limit on Windows (registry / sysinternals investigation)","Restart komorebi to release exhausted handles","Replace the expect with error logging and skip the connection instead of crashing the thread"],"exampleFix":"// before\nconnections.insert(addr.clone(), stream.try_clone().expect(\"stream should be cloneable\"));\n// after\nmatch stream.try_clone() {\n    Ok(clone) => { connections.insert(addr.clone(), clone); }\n    Err(e) => { tracing::error!(\"stream not cloneable for {addr}: {e}\"); continue; }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// treat try_clone as fallible and degrade gracefully\nmatch stream.try_clone() {\n    Ok(clone) => connections.insert(addr.clone(), clone),\n    Err(e) => { tracing::error!(\"try_clone failed: {e}\"); return; }\n}","preventionTips":["Avoid opening thousands of connections to komorebi in scripts","Close komorebi client connections properly","Monitor system handle counts during long sessions"],"tags":["network","tcp","panic","io"],"backgroundTag":"network-request-failed","analyzedSha":"e0709f02bfae4e503bf4640f58ee75ecbbfdbb97","analyzedAt":"2026-09-06T07:08:05.107Z","contentChangedAt":"2026-09-06T07:08:05.107Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}