libnyanpasu/clash-nyanpasu · warning
Failed to send initd signal: {e}
Error message
Failed to send initd signal: {e} What it means
The oneshot initd_tx channel used to signal that the shutdown-hook window finished initializing rejected the send, meaning the receiver was already dropped (e.g. the awaiting thread errored, panicked, or the setup future was cancelled).
Source
Thrown at backend/tauri/src/shutdown_hook.rs:172
0,
std::ptr::null_mut(),
std::ptr::null_mut(),
h_instance,
std::ptr::null_mut(),
)
};
if hidden_window.is_null() {
let err = Error::from_win32();
anyhow::bail!("Failed to create hidden window: {err}");
}
let window_handle = WindowHandle {
hwnd: hidden_window,
h_instance,
};
if let Err(e) = initd_tx.send(()) {
anyhow::bail!("Failed to send initd signal: {e}");
}
let mut msg = unsafe { std::mem::zeroed::<MSG>() };
unsafe {
loop {
let result = GetMessageW(&mut msg, window_handle.hwnd, 0, 0);
if result > 0 {
TranslateMessage(&msg);
DispatchMessageW(&msg);
} else {
let err = Error::from_win32();
tracing::error!(
"GetMessageW failed with {result}, shutdown hook thread exiting: {err}"
);
break;
}
}
}View on GitHub (pinned to f7dbce2997)
Solutions
- Check whether the receiver future/thread exited early and fix the underlying error it reported first.
- Treat a dropped receiver as cancellation: log and return cleanly instead of propagating as fatal, since the hook is already set up structurally.
- Ensure the waiter is spawned/awaited before the window thread runs, or use a tolerant send (ignore SendError).
- Add logging on the receive side to detect premature teardown.
Example fix
// before
if let Err(e) = initd_tx.send(()) {
anyhow::bail!("Failed to send initd signal: {e}");
}
// after
if let Err(e) = initd_tx.send(()) {
log::debug!("initd receiver dropped, hook teardown in progress: {e}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// keep receiver alive until send completes let (initd_tx, initd_rx) = tokio::sync::oneshot::channel::<()>(); assert!(!initd_rx.is_terminated(), "receiver already dropped");
Try / catch
if let Err(e) = initd_tx.send(()) {
// SendError only occurs when receiver dropped: treat as cancellation
log::debug!("init signal receiver gone: {}", e);
} Prevention
- Spawn the receiver future before starting the window thread that sends initd
- Never bail out of the waiter on unrelated errors before receiving the signal
- Use a tolerant (non-failing) send for one-shot init notifications
When it happens
Trigger: Calling setup_shutdown_hook when the receiving side of initd_tx has been dropped before send(()) succeeds — the spawn wrapper cancelled, or the waiter thread exited early on another error.
Common situations: Startup races where the bootstrap task is torn down while the hook thread is still initializing, or a panic in the code awaiting the init signal.
Related errors
- Local socket too many crashes
- enableLoopback exe not found
- managed target is an unsupported reparse point: {}
- cleanup tombstone already exists: {}
- Failed to get module handle: {err}
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/791304f3bde5b1d4.
Report an issue: GitHub.