kovidgoyal/kitty · warning

Multiple layouts match: {layout_name}

Error message

Multiple layouts match: {layout_name}

What it means

goto_layout received an ambiguous name that prefixes multiple enabled layouts (kitty matches by unique prefix), so it refuses to switch and keeps the current layout.

Source

Thrown at kitty/tabs.py:649

                matches.append(x)

        if not matched_layout:
            if len(prefix_matches) == 1:
                matched_layout = prefix_matches[0]
            elif len(matches) == 1:
                matched_layout = matches[0]
        if matched_layout:
            self._set_current_layout(matched_layout)
            self.relayout()
        else:
            if len(matches) == 0:
                if raise_exception:
                    raise ValueError(layout_name)
                log_error(f'Unknown or disabled layout: {layout_name}')
            elif len(matches) != 1:
                if raise_exception:
                    raise ValueError(layout_name)
                log_error(f'Multiple layouts match: {layout_name}')

    @ac(
        'lay',
        """
        Toggle the named layout

        Switches to the named layout if another layout is current, otherwise
        switches to the last used layout. Useful to "zoom" a window temporarily
        by switching to the stack layout. See also :opt:`scrollback_fill_enlarged_window`
        if you would like content from the scrollback buffer to scroll down into the
        zoomed window. For example::

            map f1 toggle_layout stack
        """,
    )
    def toggle_layout(self, layout_name: str) -> None:
        if self._current_layout_name == layout_name:
            self.last_used_layout()

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Use the full layout name instead of an ambiguous prefix
  2. Run kitten @get-enabled-layouts and choose a prefix unique among enabled layouts

Example fix

# before
map f1 goto_layout s

# after
map f1 goto_layout splits
Defensive patterns

Strategy: validation

Validate before calling

matches = [l for l in enabled_layouts if l.startswith(prefix)]
assert len(matches) == 1, f'ambiguous layout prefix {prefix}: {matches}'

Type guard

def is_unambiguous_prefix(p: str, enabled: list[str]) -> bool:
    return sum(l.startswith(p) for l in enabled) == 1

Prevention

When it happens

Trigger: len(matches) != 1 with raise_exception=False — e.g. goto_layout('s') when both 'splits' and 'stack' are enabled.

Common situations: Short map bindings using a layout prefix that becomes ambiguous after enabling more layouts.

Related errors


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