kovidgoyal/kitty · error · ValueError

Mark group in marker specification is not an integer: {parts

Error message

Mark group in marker specification is not an integer: {parts[i]}

What it means

In parse_marker_spec, every even-indexed part is the mark group number and is passed through int(); if that raises, the ValueError 'Mark group ... is not an integer' names the offending token. The int result is clamped to 1..3.

Source

Thrown at kitty/options/utils.py:436

    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
        if not parts or len(parts) % 2 != 0:
            raise ValueError('Mark group number and text/regex are not specified in pairs: {}'.format(' '.join(parts)))
        ans = []
        for i in range(0, len(parts), 2):
            try:
                color = max(1, min(int(parts[i]), 3))
            except Exception:
                raise ValueError(f'Mark group in marker specification is not an integer: {parts[i]}')
            sspec = parts[i + 1]
            if 'regex' not in ftype:
                sspec = re.escape(sspec)
            ans.append((color, sspec))
        ftype = 'regex'
        spec: str | tuple[tuple[int, str], ...] = tuple(ans)
    elif ftype == 'function':
        spec = ' '.join(parts)
    else:
        raise ValueError(f'Unknown marker type: {ftype}')
    return ftype, spec, flags


@func_with_args('toggle_marker')
def toggle_marker(func: str, rest: str) -> FuncArgsType:
    parts = rest.split(maxsplit=1)
    if len(parts) != 2:
        raise ValueError(f'{rest} is not a valid marker specification')

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Make every group token a plain integer (it will be clamped to 1-3)
  2. Order is: group number then pattern, repeated in pairs
  3. Sanitize script-generated specs so group tokens are digits

Example fix

# before
kitty @action set_marker text red ERROR
# after
kitty @action set_marker text 1 ERROR
Defensive patterns

Strategy: validation

Validate before calling

for i in range(0, len(parts), 2):
    if not parts[i].lstrip('-').isdigit():
        raise SystemExit(f'group not an integer: {parts[i]}')

Type guard

def is_integer_group(tok: str) -> bool:
    return tok.lstrip('-').isdigit() and int(tok) is not None

Try / catch

try:
    group = int(tok)
except ValueError:
    group = 1  # clamp fallback

Prevention

When it happens

Trigger: Calling set_marker with a non-numeric group token, e.g. `set_marker text one ERROR` or `set_marker regex 1x foo`, where parts[i]='one'/'1x' fails int().

Common situations: Users putting the pattern first and group second; alpha words like 'one'; stray characters glued to the number; scripts interpolating None/empty values into the spec.

Related errors


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