libnyanpasu/clash-nyanpasu · error

Failed to create hidden window: {err}

Error message

Failed to create hidden window: {err}

What it means

CreateWindowExW returned a null HWND when creating the hidden 'TAURI_SHUTDOWN_HOOK_WINDOW' window, so the shutdown hook cannot receive its notification message. The last Win32 error is surfaced via Error::from_win32().

Source

Thrown at backend/tauri/src/shutdown_hook.rs:163

    let hidden_window = unsafe {
        CreateWindowExW(
            WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE,
            class_name.as_ptr(),
            window_name.as_ptr(),
            0,
            0,
            0,
            0,
            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);

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Read the from_win32 error (GetLastError) to pinpoint the cause (e.g. access denied, invalid parameter).
  2. Ensure the process runs in an interactive session; services running as SYSTEM on a non-interactive window station cannot create such windows.
  3. Verify the class was registered successfully in the same hInstance before CreateWindowExW.
  4. Retry creation or degrade to a hook-less shutdown path.

Example fix

// before
if hidden_window.is_null() {
    let err = Error::from_win32();
    anyhow::bail!("Failed to create hidden window: {err}");
}
// after
if hidden_window.is_null() {
    let err = Error::from_win32();
    log::warn!("hidden shutdown window creation failed ({err}); skipping hook");
    return Ok(());
}
Defensive patterns

Strategy: fallback

Validate before calling

// non-interactive session heuristic (Windows)
fn has_interactive_desktop() -> bool {
    unsafe { !GetConsoleWindow().is_null() || !GetDesktopWindow().is_null() }
}

Try / catch

let hook = setup_shutdown_hook().await;
let shutdown_hook = match hook {
    Ok(h) => Some(h),
    Err(e) => { log::warn!("shutdown hook disabled: {e:#}"); None }
};

Prevention

When it happens

Trigger: Calling setup_shutdown_hook on Windows when window creation fails — invalid parent/style params, desktop or window-station access restrictions, or running in a non-interactive session/service context.

Common situations: Running the app as a Windows service or from a session without interactive desktop access, or resource exhaustion preventing window creation.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/b0367fd71ab50560. Report an issue: GitHub.