libnyanpasu/clash-nyanpasu · error
failed to create tokio runtime
Error message
failed to create tokio runtime
What it means
listen() spawns a thread that builds a current-thread tokio runtime via Builder::build().expect(). Runtime construction can fail (e.g. when a required IO/driver feature is disabled or resources are unavailable), and the library panics instead of returning an error because it runs on a background thread.
Source
Thrown at backend/tauri-plugin-deep-link/src/windows.rs:89
static CRASH_COUNT: AtomicU16 = AtomicU16::new(0);
pub fn listen<F: FnMut(String) + Send + 'static>(mut handler: F) -> Result<()> {
if CRASH_COUNT.load(Ordering::Acquire) > 5 {
panic!("Local socket too many crashes");
}
std::thread::spawn(move || {
let name = ID
.get()
.expect("listen() called before prepare()")
.as_str()
.to_ns_name::<GenericNamespaced>()
.unwrap();
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("failed to create tokio runtime")
.block_on(async move {
let sdsf = "D:(A;;GA;;;WD)".to_wtf_16().unwrap();
let sd = SecurityDescriptor::deserialize(&sdsf).expect("Failed to deserialize SD");
let listener = ListenerOptions::new()
.name(name)
.nonblocking(ListenerNonblockingMode::Both)
.security_descriptor(sd)
.create_tokio()
.expect("Can't create listener");
loop {
match listener.accept().await {
Ok(conn) => {
let (rx, mut tx) = conn.split();
let mut reader = BufReader::new(rx);
let mut buf = String::new();
if let Err(e) = reader.read_line(&mut buf).await {
log::error!("Error reading from connection: {e}");View on GitHub (pinned to f7dbce2997)
Solutions
- Ensure the tokio dependency includes features ["rt", "net", "macros"] (or just use default features)
- Check for workspace dependency unification stripping tokio features (cargo tree -i tokio)
- If the failure persists, restructure to run the listener on an existing tokio runtime instead of building a new one
Example fix
// before
tokio = { version = "1", default-features = false }
// after
tokio = { version = "1", features = ["rt", "net", "macros"] } Defensive patterns
Strategy: retry
Validate before calling
// ensure tokio features are enabled in Cargo.toml:
// tokio = { version = "1", features = ["rt", "net", "macros"] }
let rt = match tokio::runtime::Builder::new_current_thread().enable_all().build() {
Ok(rt) => rt,
Err(e) => { log::error!("tokio runtime: {e}"); return; }
}; Try / catch
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all().build()
.expect("failed to create tokio runtime: check tokio 'rt'/'net' features"); Prevention
- Keep tokio default features or explicitly enable rt+net+macros
- Run cargo tree -i tokio to detect feature-stripping unification
- Avoid default-features = false on tokio without re-adding needed features
When it happens
Trigger: tokio built without the features this listener needs (rt, net, etc.) so enable_all()/build() fails; pathological environments where runtime creation fails (resource exhaustion).
Common situations: Dependency conflicts downgrading/disabling tokio features (e.g. another crate enabling default-features = false); minimal builds missing 'net'/'rt' features; running in heavily restricted environments.
Related errors
- register() called before prepare()
- listen() called before prepare()
- Failed to deserialize SD
- Can't create listener
- URL not provided
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/c65ddc92c260468f.
Report an issue: GitHub.