LGUG2Z/komorebi · error

could not find device_id for hmonitor: {hmonitor}

Error message

could not find device_id for hmonitor: {hmonitor}

What it means

monitor resolves a monitor handle (HMONITOR) to its device id by iterating EnumDisplayDevices/monitor enumeration. If no device id matches the given hmonitor, komorebi bails with 'could not find device_id for hmonitor: {hmonitor}'. It means the handle does not correspond to any display device komorebi can enumerate.

Source

Thrown at komorebi/src/windows_api.rs:1142

                        display.serial_number_id = None;
                    }
                }

                let monitor = monitor::new(
                    hmonitor,
                    display.size.into(),
                    display.work_area_size.into(),
                    name,
                    device,
                    device_id,
                    display.serial_number_id,
                );

                return Ok(monitor);
            }
        }

        bail!("could not find device_id for hmonitor: {hmonitor}");
    }

    pub fn set_process_dpi_awareness_context() -> eyre::Result<()> {
        unsafe { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) }
            .process()
    }

    #[allow(dead_code)]
    pub fn system_parameters_info_w(
        action: SYSTEM_PARAMETERS_INFO_ACTION,
        ui_param: u32,
        pv_param: *mut c_void,
        update_flags: SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS,
    ) -> eyre::Result<()> {
        unsafe { SystemParametersInfoW(action, ui_param, Option::from(pv_param), update_flags) }
            .process()
    }

View on GitHub (pinned to e0709f02bf)

Solutions

  1. Re-query the current monitor handles after any display topology change and retry
  2. Verify the hmonitor value comes from a fresh EnumDisplayMonitors call
  3. Restart komorebi after connecting/disconnecting monitors so it rebuilds its monitor list
  4. Check display driver/RDP quirks; ensure the virtual display is a real enumerated device

Example fix

// before
let device_id = WindowsApi::monitor(old_hmonitor)?;
// after
let device_id = WindowsApi::monitor(current_hmonitor)
    .with_context(|| format!("stale hmonitor {old_hmonitor}; rescan displays"))?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the hmonitor is currently enumerated
fn hmonitor_is_current(hmonitor: isize, current: &[isize]) -> bool {
    current.contains(&hmonitor)
}

Try / catch

match WindowsApi::monitor(hmonitor) {
    Ok(device_id) => device_id,
    Err(e) if e.to_string().contains("could not find device_id") => {
        log::warn!("stale hmonitor {hmonitor}; rescanning display topology");
        rescan_monitors()?;
        WindowsApi::monitor(fresh_hmonitor)?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling WindowsApi::monitor(hmonitor) with an HMONITOR that is invalid, stale (monitor unplugged or topology changed), or one that display enumeration does not return (virtual/RDP display edge cases).

Common situations: Hot-plugging monitors or changing display topology while komorebi is running; RDP or virtual display adapters whose HMONITORs aren't matched by EnumDisplayDevices; passing a hardcoded/invalid monitor handle.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of LGUG2Z/komorebi@e0709f02bf (2026-09-06). Data as JSON: /api/errors/33b3c1ec79378bd3. Report an issue: GitHub.