LGUG2Z/komorebi · error

cannot move native maximized window to another monitor or wo

Error message

cannot move native maximized window to another monitor or workspace

What it means

Monitor::move_container_to_workspace refuses to move a container when the target workspace has a native (Windows) maximized window, because moving a window into a monitor/workspace with a natively maximized window would break the maximized state invariant. It bails with this error.

Source

Thrown at komorebi/src/monitor.rs:395

    }

    pub fn remove_workspaces(&mut self) -> VecDeque<Workspace> {
        std::mem::take(self.workspaces_mut())
    }

    #[tracing::instrument(skip(self))]
    pub fn move_container_to_workspace(
        &mut self,
        target_workspace_idx: usize,
        follow: bool,
        direction: Option<OperationDirection>,
    ) -> eyre::Result<()> {
        let workspace = self
            .focused_workspace_mut()
            .ok_or_eyre("there is no workspace")?;

        if workspace.maximized_window.is_some() {
            bail!("cannot move native maximized window to another monitor or workspace");
        }

        let foreground_hwnd = WindowsApi::foreground_window()?;
        let floating_window_index = workspace
            .floating_windows()
            .iter()
            .position(|w| w.hwnd == foreground_hwnd);

        if let Some(idx) = floating_window_index {
            if let Some(window) = workspace.floating_windows_mut().remove(idx) {
                let workspaces = self.workspaces_mut();
                #[allow(clippy::option_if_let_else)]
                let target_workspace = match workspaces.get_mut(target_workspace_idx) {
                    None => {
                        workspaces.resize(target_workspace_idx + 1, Workspace::default());
                        workspaces.get_mut(target_workspace_idx).unwrap()
                    }
                    Some(workspace) => workspace,

View on GitHub (pinned to e0709f02bf)

Solutions

  1. Restore/unmaximize the window on the destination workspace before moving, then re-run the move.
  2. Switch the destination workspace to use komorebi's managed maximize (komorebic promote / resize) instead of native maximize.
  3. Check first via query whether the target workspace has a maximized window and skip/queue the move in scripts.

Example fix

// before
komorebic move-to-workspace 3   # fails: native maximized window on ws 3
// after
komorebic cycle-move-monitor  # or first: focus ws 3 and restore the maximized window
komorebic move-to-workspace 3
Defensive patterns

Strategy: validation

Validate before calling

// PowerShell pre-check before move-to-workspace keybind/script
# skip the move if the target workspace has a native maximized window
komorebic state | Select-String 'Maximized'

Type guard

fn can_move_to(workspace: &Workspace) -> bool {
    workspace.maximized_window.is_none()
}

Try / catch

if let Err(e) = monitor.move_container_to_workspace(idx) {
    tracing::warn!("move skipped: {e}; unmaximize the target workspace window first");
}

Prevention

When it happens

Trigger: Calling move_container_to_workspace (or komorebic commands like move-to-workspace / cycle-move) when the destination workspace's maximized_window is Some, i.e. a window is natively maximized there (MaximizedLayout / native maximize).

Common situations: User presses move-to-workspace keybind while a video/game/terminal is natively maximized on the destination workspace; scripts iterating workspaces that hit a maximized window.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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