glzr-io/glazewm · error
IPC connection closed unexpectedly.
Error message
IPC connection closed unexpectedly.
What it means
The watcher process keeps an open IPC connection to the main WM while it watches managed window handles. If the event stream returns `None` — the WebSocket closed without the WM first sending `WmEvent::ApplicationExiting` — the watcher treats this as an abnormal shutdown and bails.
Solutions
- Restart the watcher/main WM processes so a fresh IPC connection is established
- Check the main WM logs for a crash explaining the abrupt disconnect
- If intentional cleanup is needed, have the WM emit `WmEvent::ApplicationExiting` before closing the IPC connection
Defensive patterns
Strategy: try-catch
Try / catch
match watcher::watch_managed_handles() {
Ok(()) => {}
Err(e) if e.to_string().contains("IPC connection closed unexpectedly") => {
tracing::warn!("WM exited without ApplicationExiting event; cleaning up");
}
Err(e) => return Err(e),
} Prevention
- Ensure the WM emits WmEvent::ApplicationExiting before shutting down
- Monitor the WM process health from the watcher
- Implement reconnect/backoff if the connection should be transient
When it happens
Trigger: The main glazewm.exe process is killed/crashes, the IPC socket drops mid-session, or the watcher loses the connection before receiving the graceful `ApplicationExiting` event.
Common situations: Force-killing the WM from Task Manager, WM crash, system shutdown forcibly terminating the parent, or an IPC server bug closing the socket.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
AI-assisted analysis of glzr-io/glazewm@5709ad0a3c (2026-09-08).
Data as JSON: /api/errors/d21f2da97d7c4e4f.
Report an issue: GitHub.
Appendix: source
Thrown at packages/wm-watcher/src/main.rs:136
match event_data {
Some(WmEvent::WindowManaged { managed_window }) => {
if let ContainerDto::Window(window) = managed_window {
tracing::info!("Watcher added handle: {}.", window.handle);
handles.push(window.handle);
}
}
Some(WmEvent::WindowUnmanaged {
unmanaged_handle, ..
}) => {
tracing::info!("Watcher removed handle: {}.", unmanaged_handle);
handles.retain(|&handle| handle != unmanaged_handle);
}
Some(WmEvent::ApplicationExiting) => {
return Ok(());
}
Some(_) => unreachable!(),
None => {
anyhow::bail!("IPC connection closed unexpectedly.")
}
}
}
}
View on GitHub (pinned to 5709ad0a3c)