LGUG2Z/komorebi · error

stream should be cloneable

Error message

stream should be cloneable

What it means

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).

Source

Thrown at komorebi/src/process_command.rs:168

    std::thread::spawn(move || {
        tracing::info!("listening on 0.0.0.0:43663");
        for client in listener.incoming() {
            match client {
                Ok(mut stream) => {
                    net2::TcpStreamExt::set_keepalive(&stream, Some(Duration::from_secs(30)))
                        .expect("TCP keepalive should be set");

                    let addr = stream
                        .peer_addr()
                        .expect("incoming connection should have an address")
                        .to_string();

                    let mut connections = TCP_CONNECTIONS.lock();

                    connections.insert(
                        addr.clone(),
                        stream.try_clone().expect("stream should be cloneable"),
                    );

                    tracing::info!("listening for incoming tcp messages from {}", &addr);

                    match read_commands_tcp(&wm, &mut stream, &addr) {
                        Ok(()) => {}
                        Err(error) => tracing::error!("{}", error),
                    }
                }
                Err(error) => {
                    tracing::error!("{}", error);
                    break;
                }
            }
        }
    });
}

View on GitHub (pinned to e0709f02bf)

Solutions

  1. Check for socket/handle leaks in the system (close idle connections to komorebi)
  2. Raise the per-process handle limit on Windows (registry / sysinternals investigation)
  3. Restart komorebi to release exhausted handles
  4. Replace the expect with error logging and skip the connection instead of crashing the thread

Example fix

// before
connections.insert(addr.clone(), stream.try_clone().expect("stream should be cloneable"));
// after
match stream.try_clone() {
    Ok(clone) => { connections.insert(addr.clone(), clone); }
    Err(e) => { tracing::error!("stream not cloneable for {addr}: {e}"); continue; }
}
Defensive patterns

Strategy: try-catch

Try / catch

// treat try_clone as fallible and degrade gracefully
match stream.try_clone() {
    Ok(clone) => connections.insert(addr.clone(), clone),
    Err(e) => { tracing::error!("try_clone failed: {e}"); return; }
}

Prevention

When it happens

Trigger: stream.try_clone() returns Err while registering an accepted connection in TCP_CONNECTIONS — practically only under handle/fd exhaustion or on exotic platforms.

Common situations: System running out of file/socket handles after many connections; resource limits hit during long-running sessions.

Related errors


AI-assisted analysis of LGUG2Z/komorebi@e0709f02bf (2026-09-06). Data as JSON: /api/errors/ee72c5859f8430b6. Report an issue: GitHub.