kovidgoyal/kitty · error · RemoteControlErrorWithoutTraceback

There is no active OS window to screenshot

Error message

There is no active OS window to screenshot

What it means

Raised by the remote-control screenshot command when no OS window currently has focus/exists to capture. kitty can only screenshot a visible OS window; if there is no active tab manager (e.g. all windows closed or kitty is running headless), the command aborts.

Solutions

  1. Ensure at least one OS window is open in the kitty instance before issuing the screenshot command
  2. Pass a --match for a specific visible tab so the code path that resolves a tab's os_window_id is used instead
  3. Retry after verifying kitty is running with windows open
Defensive patterns

Strategy: validation

Validate before calling

import subprocess
# ensure kitty has windows before screenshotting
def kitty_has_windows():
    out = subprocess.run(['kitten','@ls'],capture_output=True).stdout
    return b'os_window_id' in out

Prevention

When it happens

Trigger: Running @screenshot via remote control without a --match for a tab while boss.active_tab_manager is None (no OS windows exist).

Common situations: Scripting kitty remote control while kitty has no open windows, or during startup/shutdown races.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/353379677dfd4cbb. Report an issue: GitHub.

Appendix: source

Thrown at kitty/rc/screenshot.py:95

            tab = w.tabref()
            tm = tab.tab_manager_ref() if tab is not None else None
            if tab is None or tm is None or tm.active_tab is not tab or not w.is_visible_in_layout:
                raise RemoteControlErrorWithoutTraceback('The matched window is not currently visible, screenshots can only be taken of visible windows')
            os_window_id = w.os_window_id
            target_window_id = w.id
        elif match_tab:
            tabs = list(boss.match_tabs(match_tab))
            if not tabs:
                raise MatchError(match_tab, 'tabs')
            tab = tabs[0]
            tm = tab.tab_manager_ref()
            if tm is None or tm.active_tab is not tab:
                raise RemoteControlErrorWithoutTraceback('The matched tab is not currently visible, screenshots can only be taken of visible tabs')
            os_window_id = tab.os_window_id
        else:
            atm = boss.active_tab_manager
            if atm is None:
                raise RemoteControlErrorWithoutTraceback('There is no active OS window to screenshot')
            os_window_id = atm.os_window_id
            include_tab_bar = True

        output_path = payload_get('output_path') or ''
        responder = self.create_async_responder(payload_get, window)

        def callback(cb_os_window_id: int, cb_window_id: int, pixels: bytes, width: int, height: int) -> None:
            if not pixels:
                responder.send_error('Failed to take screenshot, the OS window may have been closed')
                return
            try:
                png_data = png_from_32bit_rgba_data(pixels, width, height, True)
                if output_path:
                    with open(os.path.expanduser(output_path), 'wb') as f:
                        f.write(png_data)
                    responder.send_data(f'Screenshot saved to: {os.path.abspath(f.name)}')
                else:
                    responder.send_data(standard_b64encode(png_data).decode('ascii'))

View on GitHub (pinned to 6d5d0c4406)