kovidgoyal/kitty · error · ValueError

{where} is not a valid set of windows to disable ligatures i

Error message

{where} is not a valid set of windows to disable ligatures in

What it means

disable_ligatures_in parses the disable_ligatures action arguments as [where] strategy. where must be active, all, or tab; anything else raises ValueError. If only one word is given it defaults to where='active'.

Source

Thrown at kitty/options/utils.py:410

@func_with_args('sleep')
def sleep(func: str, sleep_time: str) -> FuncArgsType:
    mult = 1
    sleep_time = sleep_time or '1'
    if sleep_time[-1] in 'shmd':
        mult = {'s': 1, 'm': 60, 'h': 3600, 'd': 24 * 3600}[sleep_time[-1]]
        sleep_time = sleep_time[:-1]
    return func, [abs(float(sleep_time)) * mult]


@func_with_args('disable_ligatures_in')
def disable_ligatures_in(func: str, rest: str) -> FuncArgsType:
    parts = rest.split(maxsplit=1)
    if len(parts) == 1:
        where, strategy = 'active', parts[0]
    else:
        where, strategy = parts
    if where not in ('active', 'all', 'tab'):
        raise ValueError(f'{where} is not a valid set of windows to disable ligatures in')
    if strategy not in ('never', 'always', 'cursor'):
        raise ValueError(f'{strategy} is not a valid disable ligatures strategy')
    return func, [where, strategy]


@func_with_args('layout_action')
def layout_action(func: str, rest: str) -> FuncArgsType:
    parts = rest.split(maxsplit=1)
    if not parts:
        raise ValueError('layout_action must have at least one argument')
    return func, [parts[0], tuple(parts[1:])]


def parse_marker_spec(ftype: str, parts: Sequence[str]) -> tuple[str, str | tuple[tuple[int, str], ...], int]:
    flags = re.UNICODE
    if ftype in ('text', 'itext', 'regex', 'iregex'):
        if ftype.startswith('i'):
            flags |= re.IGNORECASE

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Put the scope first: active, all, or tab; then the strategy (never/always/cursor)
  2. For a single-window toggle use `disable_ligatures active always` or just the strategy alone to default to active
  3. Check argument order — two tokens means [where, strategy]

Example fix

# before
disable_ligatures window never
# after
disable_ligatures tab never
Defensive patterns

Strategy: validation

Validate before calling

parts = rest.split(maxsplit=1)
where, strategy = ('active', parts[0]) if len(parts) == 1 else parts
if where not in ('active','all','tab'):
    raise SystemExit(f'bad where: {where}')

Type guard

def is_ligature_where(v: str) -> bool:
    return v in ('active','all','tab')

Prevention

When it happens

Trigger: A map/launch line like `disable_ligatures window never` or `disable_ligatures everywhere always` — the first token is validated against ('active','all','tab').

Common situations: Users writing `disable_ligatures cursor` (strategy keyword first, forgetting the where token); guessing 'window' or 'everywhere' as scope names; misordered arguments.

Related errors


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