Hmbown/CodeWhale · warning · io::Error

the per-session control socket is unix-only

Error message

the per-session control socket is unix-only

What it means

bind_control_socket is the non-Unix (e.g. Windows) stub of the per-session control socket API. On platforms other than Unix it unconditionally returns ErrorKind::Unsupported with this message — the control socket feature is simply not implemented there.

Solutions

  1. Run on a Unix platform (Linux/macOS) if the control socket is required
  2. Guard the caller with a platform check and skip control-socket setup on non-Unix targets
  3. Treat the returned ErrorKind::Unsupported as 'feature unavailable' and degrade gracefully
  4. Implement or request a Windows transport (e.g. named pipes) for the control socket

Example fix

// before
let handle = bind_control_socket(&dir, &id, tx, status)?;
// after
let handle = if cfg!(unix) {
    Some(bind_control_socket(&dir, &id, tx, status)?)
} else {
    None // control socket unsupported on this platform
};
Defensive patterns

Strategy: fallback

Validate before calling

let supported = cfg!(unix);
if !supported {
    // skip control-socket setup entirely
}

Try / catch

match bind_control_socket(&dir, &id, tx, status) {
    Ok(h) => Some(h),
    Err(e) if e.kind() == io::ErrorKind::Unsupported => None,
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling bind_control_socket on a non-Unix target (the cfg-gated stub at control_socket.rs:658), e.g. building/running the TUI on Windows and trying to start the session control server.

Common situations: Running Codewhale on Windows where per-session command sockets were never implemented; cross-platform code paths that assume the socket always binds.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/c87e8be1996fd424. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/control_socket.rs:658

    let thread_stop = Arc::clone(&stop);
    let thread = thread::Builder::new()
        .name(format!("codewhale-control-{session_id}"))
        .spawn(move || serve(listener, path, identity, thread_stop, commands_tx, status))?;

    Ok(ControlSocketHandle {
        stop,
        thread: Some(thread),
    })
}

#[cfg(not(unix))]
pub(crate) fn bind_control_socket(
    _sessions_dir: &Path,
    _session_id: &str,
    _commands_tx: mpsc::Sender<PendingCommand>,
    _status: Arc<Mutex<StatusSnapshot>>,
) -> io::Result<ControlSocketHandle> {
    Err(io::Error::new(
        io::ErrorKind::Unsupported,
        "the per-session control socket is unix-only",
    ))
}

/// Take over the socket path, or refuse when a live server already holds it.
#[cfg(unix)]
fn prepare_socket_path(path: &Path) -> io::Result<()> {
    match fs::symlink_metadata(path) {
        Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(()),
        Err(error) => Err(error),
        Ok(metadata) => {
            if !metadata.file_type().is_socket() {
                // A plain file (or directory) in the way: not ours to keep.
                fs::remove_file(path)?;
                return Ok(());
            }
            match UnixStream::connect(path) {

View on GitHub (pinned to 73e0f67d83)