{"record":{"id":"421332fb213ecec7","repo":"LGUG2Z/komorebi","slug":"this-is-not-a-valid-monitor-index","errorCode":null,"errorMessage":"this is not a valid monitor index","messagePattern":"this is not a valid monitor index","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"komorebi/src/window_manager.rs","lineNumber":3702,"sourceCode":"            .ok_or_eyre(\"there is no monitor\")?\n            .size)\n    }\n\n    pub fn focused_monitor_work_area(&self) -> eyre::Result<Rect> {\n        Ok(self\n            .focused_monitor()\n            .ok_or_eyre(\"there is no monitor\")?\n            .work_area_size)\n    }\n\n    #[tracing::instrument(skip(self))]\n    pub fn focus_monitor(&mut self, idx: usize) -> eyre::Result<()> {\n        tracing::info!(\"focusing monitor\");\n\n        if self.monitors().get(idx).is_some() {\n            self.monitors.focus(idx);\n        } else {\n            bail!(\"this is not a valid monitor index\");\n        }\n\n        Ok(())\n    }\n\n    pub fn monitor_idx_from_window(&mut self, window: Window) -> Option<usize> {\n        let hmonitor = WindowsApi::monitor_from_window(window.hwnd);\n\n        for (i, monitor) in self.monitors().iter().enumerate() {\n            if monitor.id == hmonitor {\n                return Option::from(i);\n            }\n        }\n\n        // our hmonitor might be stale, so if we didn't return above, try querying via the latest\n        // info taken from win32_display_data and update our hmonitor while we're at it\n        if let Ok(latest) = WindowsApi::monitor(hmonitor) {\n            for (i, monitor) in self.monitors_mut().iter_mut().enumerate() {","sourceCodeStart":3684,"sourceCodeEnd":3720,"githubUrl":"https://github.com/LGUG2Z/komorebi/blob/e0709f02bfae4e503bf4640f58ee75ecbbfdbb97/komorebi/src/window_manager.rs#L3684-L3720","documentation":"focus_monitor validates the requested monitor index against the number of entries in self.monitors. If monitors.get(idx) is None — the index exceeds the connected/virtual monitor count — the command fails with this message instead of panicking on an out-of-bounds access.","triggerScenarios":"Calling focus_monitor(idx) (komorebic focus-monitor N, monitor cycling with saved configs) where idx >= monitors.len(), e.g. index 2 on a single-monitor setup, or after a monitor was disconnected.","commonSituations":"Sharing komorebi.json keybinds across machines with different monitor counts; hotplug changes (undocking a laptop) invalidating previously valid indexes; scripts with hardcoded indexes.","solutions":["Query the current monitor count (komorebic query state / OS APIs) and clamp the index before calling focus_monitor","Use relative cycling (komorebic cycle-monitor) instead of absolute indexes","Regenerate or parameterize configs per machine rather than hardcoding monitor indexes","Catch the error and fall back to the primary monitor"],"exampleFix":"// before\nkomorebic focus-monitor 2 // fails on 2-monitor setup (indexes 0..1)\n// after\nkomorebic cycle-monitor  # relative cycling avoids out-of-range indexes","handlingStrategy":"validation","validationCode":"let monitor_count = query_korebi_monitor_count(); // e.g. via komorebic query\nif idx < monitor_count { komorebic focus-monitor idx }\nelse { komorebic focus-monitor 0 }","typeGuard":null,"tryCatchPattern":"// fallback to primary monitor\nmatch wm.focus_monitor(idx) {\n    Err(_) => wm.focus_monitor(0),\n    ok => ok,\n}","preventionTips":["Never hardcode monitor indexes in shared configs; compute from the live monitor count","Handle monitor hotplug events by refreshing saved indexes","Prefer cycle-monitor (relative) over absolute indexes"],"tags":["windows","window-manager","monitor","index-out-of-bounds"],"backgroundTag":"index-out-of-range","analyzedSha":"e0709f02bfae4e503bf4640f58ee75ecbbfdbb97","analyzedAt":"2026-09-06T07:08:05.107Z","contentChangedAt":"2026-09-06T07:08:05.107Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}