elkowar/eww · error

Failed to initialize tokio runtime

Error message

Failed to initialize tokio runtime

What it means

`listen_for_daemon_response` builds a dedicated single-thread tokio runtime to await a short-timeout daemon response. `Runtime::build()` returned an Err and `expect` panicked with this message. Runtime construction fails under unsupported or restricted runtime configurations (e.g. io/time drivers unavailable in this build/thread context).

Solutions

  1. Ensure Cargo.toml enables full tokio features: `tokio = { version = "1", features = ["full"] }`.
  2. Rebuild/upgrade tokio and eww to resolve build-feature mismatches.
  3. If embedding, avoid constructing runtimes inside another runtime thread; run this path on a plain thread.

Example fix

// Cargo.toml before
tokio = "1"
// after
tokio = { version = "1", features = ["full"] }
Defensive patterns

Strategy: try-catch

Validate before calling

// build-time check: ensure tokio features
// tokio = { version = "1", features = ["full"] }

Try / catch

let rt = tokio::runtime::Builder::new_current_thread().enable_all().build()
    .map_err(|e| anyhow::anyhow!("failed to init runtime: {e}"))?;

Prevention

When it happens

Trigger: Calling `listen_for_daemon_response` (from `run`) when `tokio::runtime::Builder::new_current_thread().enable_all().build()` fails.

Common situations: Building against a tokio feature set lacking required drivers (missing `rt`, `time`, or `net` features); exotic embedded environments; extremely constrained systems.


AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08). Data as JSON: /api/errors/d750a7ee2a894939. Report an issue: GitHub.

Appendix: source

Thrown at crates/eww/src/main.rs:189

                    is_parent
                }
                Err(err) => Err(err)?,
            }
        }
    };

    if would_show_logs && opts.show_logs {
        client::handle_client_only_action(&paths, opts::ActionClientOnly::Logs)?;
    }
    Ok(())
}

fn listen_for_daemon_response(mut recv: DaemonResponseReceiver) {
    let rt = tokio::runtime::Builder::new_current_thread()
        .thread_name("listen-for-daemon-response")
        .enable_all()
        .build()
        .expect("Failed to initialize tokio runtime");
    rt.block_on(async {
        if let Ok(Some(response)) = tokio::time::timeout(Duration::from_millis(100), recv.recv()).await {
            println!("{}", response);
        }
    })
}

/// attempt to send a command to the daemon and send it the given action repeatedly.
fn handle_server_command(paths: &EwwPaths, action: &ActionWithServer, connect_attempts: usize) -> Result<Option<DaemonResponse>> {
    log::debug!("Trying to find server process at socket {}", paths.get_ipc_socket_file().display());
    let mut stream = attempt_connect(paths.get_ipc_socket_file(), connect_attempts).context("Failed to connect to daemon")?;
    log::debug!("Connected to Eww server ({}).", &paths.get_ipc_socket_file().display());
    client::do_server_call(&mut stream, action).context("Error while forwarding command to server")
}

fn handle_daemon_response(res: DaemonResponse) {
    match res {
        DaemonResponse::Success(x) => println!("{}", x),

View on GitHub (pinned to 48f5aa8b37)