GraphiteEditor/Graphite · critical
CreateWindowExW failed
Error message
CreateWindowExW failed
What it means
Panic when the Win32 CreateWindowExW call returns a null HWND. In this code the window being created is the helper window used to subclass the main window (the main window's HWND is passed through WM_NCCREATE so the helper can store it). A null return means the OS refused window creation: the window class was not registered, invalid parameters, exhaustion of USER/GDI handles, or broken session state.
Source
Thrown at desktop/src/window/win/native_handle.rs:71
let style = WS_POPUP;
let helper = unsafe {
CreateWindowExW(
ex,
PCWSTR(HELPER_CLASS_NAME.encode_utf16().collect::<Vec<_>>().as_ptr()),
PCWSTR::null(),
style,
0,
0,
0,
0,
Some(main),
None,
None,
// Pass the main window's HWND to WM_NCCREATE so the helper can store it.
Some(&main as *const _ as _),
)
}
.expect("CreateWindowExW failed");
// Subclass the main window.
// https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-setwindowlongptra
let prev_window_message_handler = unsafe { SetWindowLongPtrW(main, GWLP_WNDPROC, main_window_handle_message as *const () as isize) };
if prev_window_message_handler == 0 {
let _ = unsafe { DestroyWindow(helper) };
panic!("SetWindowLongPtrW failed");
}
let native_handle = NativeWindowHandle {
main,
helper,
prev_window_message_handler,
state: Arc::new(Mutex::new(NativeWindowState::default())),
};
registry::insert(&native_handle);
// Place the helper over the main window and show it without activation.View on GitHub (pinned to c507b35645)
Solutions
- Capture GetLastError at the failure site (or via a debugger) to get the exact Win32 error code (ERROR_CLASS_DOES_NOT_EXIST, ERROR_NOT_ENOUGH_MEMORY, etc.)
- Check handle usage in Task Manager (Details tab, add USER objects/GDI objects columns) and close leaking applications; reboot clears session handle leaks
- Verify the class registration code path always runs before CreateWindowExW for both main and helper windows
- Reconnect the RDP session or reboot if session state is suspected corrupt
Example fix
// before
}
.expect("CreateWindowExW failed");
// after
let hwnd = { /* CreateWindowExW(...) */ };
if hwnd.is_invalid() {
let err = unsafe { GetLastError() };
panic!("CreateWindowExW failed with Win32 error {err}");
} Defensive patterns
Strategy: try-catch
Try / catch
let hwnd = unsafe { /* CreateWindowExW(...) */ };
if hwnd.is_invalid() {
let code = unsafe { windows::Win32::Foundation::GetLastError() };
panic!("CreateWindowExW failed with Win32 error {}", code.0);
} Prevention
- Always register the window class and check its result before CreateWindowExW
- Monitor USER/GDI object counts for leaks in long-running processes
- Include GetLastError in the panic message; the raw message hides the OS reason
When it happens
Trigger: The window class for the helper window was never registered or registration failed silently earlier; USER/GDI handle exhaustion in the process or session (handle leak in the app or other apps); running in a broken or disconnected RDP session; out of memory for window objects.
Common situations: Long-running sessions where a leaking application exhausted the ~10k USER handle quota per session; remote desktop reconnects leaving stale session state; antivirus or shell-replacement software interfering with window creation; low system resources at startup.
Related errors
- failed to open app
- Failed to compile Windows resources
- InvalidData
- Failed to parse input type for #[implementation(...)]. Expec
- Expected `->` arrow after input type in #[implementations(..
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/8c20c51a0077a81f.
Report an issue: GitHub.