LGUG2Z/komorebi · error
could not close window
Error message
could not close window
What it means
komorebi's close_window sends a WM_CLOSE message to the target window via the Win32 PostMessageW API. If PostMessageW returns an error (e.g. invalid handle or message refused), komorebi bails with 'could not close window'. It means the OS refused the request to close that window.
Source
Thrown at komorebi/src/windows_api.rs:672
};
} else {
unsafe {
let _ = ShowWindow(HWND(as_ptr!(hwnd)), command);
};
}
}
pub fn minimize_window(hwnd: isize) {
Self::show_window(hwnd, SW_MINIMIZE);
}
fn post_message(hwnd: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> eyre::Result<()> {
unsafe { PostMessageW(Option::from(hwnd), message, wparam, lparam) }.process()
}
pub fn close_window(hwnd: isize) -> eyre::Result<()> {
if Self::post_message(HWND(as_ptr!(hwnd)), WM_CLOSE, WPARAM(0), LPARAM(0)).is_err() {
bail!("could not close window");
}
Ok(())
}
pub fn hide_window(hwnd: isize) {
Self::show_window(hwnd, SW_HIDE);
}
pub fn restore_window(hwnd: isize) {
Self::show_window(hwnd, SW_SHOWNOACTIVATE);
}
pub fn unmaximize_window(hwnd: isize) {
Self::show_window(hwnd, SW_NORMAL);
}
pub fn maximize_window(hwnd: isize) {View on GitHub (pinned to e0709f02bf)
Solutions
- Verify the hwnd is still valid before closing (IsWindow) and refresh komorebi's window list
- Run komorebi with the same or higher privilege level as the target application
- Check that the window isn't a protected system/elevated process window; use taskkill or close it manually
- Restart komorebi to resynchronize hwnd state
Example fix
// before
WindowsApi::close_window(stale_hwnd)?;
// after
if WindowsApi::is_window(stale_hwnd) {
WindowsApi::close_window(stale_hwnd)?;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust (windows crate)
use windows::Win32::UI::WindowsAndMessaging::IsWindow;
fn can_close(hwnd: isize) -> bool {
unsafe { IsWindow(Some(HWND(hwnd as _))).as_bool() }
} Type guard
fn window_is_valid(hwnd: isize) -> bool {
hwnd != 0 && unsafe { IsWindow(Some(HWND(hwnd as _))).as_bool() }
} Try / catch
match WindowsApi::close_window(hwnd) {
Ok(()) => {},
Err(e) if e.to_string().contains("could not close window") => {
log::warn!("window {hwnd} refused WM_CLOSE or is gone; refreshing window list");
refresh_window_state();
}
Err(e) => return Err(e),
} Prevention
- Check IsWindow before sending WM_CLOSE to cached hwnds
- Run komorebi at the same elevation level as target applications
- Resubscribe/refresh hwnd state after window destroy/create events
- Avoid closing elevated or UWP system windows via WM_CLOSE
When it happens
Trigger: Calling WindowsApi::close_window(hwnd) with an hwnd that is stale/invalid, belongs to another desktop or elevated process, or when PostMessageW fails for a protected/system window.
Common situations: A window was closed or recreated between layout passes so komorebi holds a dead hwnd; attempting to close elevated (admin) application windows from a non-elevated komorebi; UWP/system windows that ignore WM_CLOSE.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- failed call to AllowSetForegroundWindow after 5 retries
- cannot move native maximized window to another monitor or wo
- window handles for move operation don't match: {} != {}
- ignoring commands while active window is not managed by komo
- could not find next window
AI-assisted analysis of LGUG2Z/komorebi@e0709f02bf (2026-09-06).
Data as JSON: /api/errors/9a5ff6fb4d8ed5bc.
Report an issue: GitHub.