kovidgoyal/kitty · warning · OSError

Failed to start tab drag: {e}

Error message

Failed to start tab drag: {e}

What it means

Starting a native drag-and-drop for a tab (dragging a tab out of the window) failed with an OSError from the platform backend; kitty resets the dragged-tab state so the UI stays consistent.

Source

Thrown at kitty/tabs.py:1921

                title = re.sub(r'[\n\r]', ' ', title)
                title = replace_c0_codes_except_nl_space_tab(title.encode()).decode()
                opts = get_options()
                if td.is_active:
                    fg = color_as_int(opts.active_tab_foreground)
                    bg = color_as_int(opts.active_tab_background)
                else:
                    fg = color_as_int(opts.inactive_tab_foreground)
                    bg = color_as_int(opts.inactive_tab_background)
                title_pixels, width = draw_single_line_of_text(self.os_window_id, title, 0xFF000000 | fg, 0xFF000000 | bg, width)
                title_height = len(title_pixels) // (width * 4)
                thumbnails = ((title_pixels, width, title_height), (title_pixels + pixels, width, title_height + height))
                drag_data = {
                    f'application/net.kovidgoyal.kitty-tab-{os.getpid()}': str(tab.id).encode(),
                }
                try:
                    start_drag_with_data(self.os_window_id, drag_data, thumbnails)
                except OSError as e:
                    log_error(f'Failed to start tab drag: {e}')
                    set_tab_being_dragged()
                    self.mark_tab_bar_dirty()  # re-render the tab bar in case it was drawn without the dragged tab
                break
        else:
            set_tab_being_dragged()

    def handle_tab_bar_mouse(self, x: float, y: float, button: int, modifiers: int, action: int) -> None:
        if button == -1:  # motion
            dragged_tab_id, drag_started, start_x, start_y = get_tab_being_dragged()
            if dragged_tab_id and self.tab_for_id(dragged_tab_id) is not None and not drag_started:
                threshold = get_options().drag_threshold
                if threshold and math.sqrt((x - start_x) ** 2 + (y - start_y) ** 2) > threshold:
                    set_tab_being_dragged(dragged_tab_id, True, start_x, start_y)
                    get_boss().request_thumbnail(self.os_window_id, get_boss().start_tab_drag)
                    self.recent_tab_bar_mouse_events.clear()
            return

        tab_id_at_pointer = self.tab_bar.tab_id_at(int(x), int(y))

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Drag within the window instead of dragging out to another kitty instance (copy/move via :cmd or remote control)
  2. Update kitty and your compositor — Wayland drag support has improved over releases
  3. File an issue with kitty including your OS/compositor and the OSError text
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: start_drag_with_data(os_window_id, drag_data, thumbnails) raises OSError during the tab drag handler in tabs.py.

Common situations: Platform/windowing limitations (some Wayland compositors restrict XDnD/mime-based drags), running under a compositor that doesn't support the drag mime type, or driver quirks.

Related errors


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