kovidgoyal/kitty · error · KeyError

{jt} is not a valid jump type for a linear easing function

Error message

{jt} is not a valid jump type for a linear easing function

What it means

For a steps() easing with two parameters, the second must be a jump type from {'jump-start','start','end','jump-end','jump-none','jump-both'} (case-insensitive); anything else raises KeyError.

Source

Thrown at kitty/options/utils.py:1719

                add_point(y, percent(points[1]))
                add_point(y, percent(points[2]))
            else:
                raise ValueError(f'{r} has too many points for a linear easing curve parameter')
        balance(1)
        return cls(type='linear', linear_x=tuple(xaxis), linear_y=tuple(yaxis))

    @classmethod
    def steps(cls, params: str) -> 'EasingFunction':
        parts = params.replace(',', ' ').split()
        jump_type: JumpTypes = 'end'
        if len(parts) == 2:
            n = int(parts[0])
            jt = parts[1]
            mapping: dict[str, JumpTypes] = {'jump-start': 'start', 'start': 'start', 'end': 'end', 'jump-end': 'end', 'jump-none': 'none', 'jump-both': 'both'}
            try:
                jump_type = mapping[jt.lower()]
            except KeyError:
                raise KeyError(f'{jt} is not a valid jump type for a linear easing function')
            if jump_type == 'none':
                n = max(2, n)
            else:
                n = max(1, n)
        else:
            n = max(1, int(parts[0]))
        return cls(type='steps', jump_type=jump_type, num_steps=n)


def parse_animation(spec: str, interval: float = -1.0) -> tuple[float, EasingFunction, EasingFunction]:
    with suppress(Exception):
        interval = float(spec)
        return interval, EasingFunction(), EasingFunction()

    m = [EasingFunction(), EasingFunction()]

    def parse_func(func_name: str, params: str) -> None:
        idx = 1 if m[0] else 0

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Use one of: jump-start, start, end, jump-end, jump-none, jump-both
  2. Omit the jump type to default to end behavior

Example fix

# before
cursor_blink_interval 0.5:steps(4, middle)
# after
cursor_blink_interval 0.5:steps(4, jump-end)
Defensive patterns

Strategy: type-guard

Validate before calling

JT = {'jump-start','start','end','jump-end','jump-none','jump-both'}
def valid_jump_type(jt: str) -> bool:
    return jt.lower() in JT

Type guard

def is_valid_jump_type(jt: str) -> bool:
    return jt.lower() in {'jump-start','start','end','jump-end','jump-none','jump-both'}

Prevention

When it happens

Trigger: 'steps(4, middle)' or 'steps(3, both-ends)' in an animation spec — unrecognized jump term names.

Common situations: Confusing kitty's/CSS steps() jump-term vocabulary, typos, or using SVG-style easing names.

Related errors


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