{"record":{"id":"74593fa7e79a115f","repo":"kovidgoyal/kitty","slug":"mark-group-in-marker-specification-is-not-an-integ","errorCode":null,"errorMessage":"Mark group in marker specification is not an integer: {parts[i]}","messagePattern":"Mark group in marker specification is not an integer: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kitty/options/utils.py","lineNumber":436,"sourceCode":"    parts = rest.split(maxsplit=1)\n    if not parts:\n        raise ValueError('layout_action must have at least one argument')\n    return func, [parts[0], tuple(parts[1:])]\n\n\ndef parse_marker_spec(ftype: str, parts: Sequence[str]) -> tuple[str, str | tuple[tuple[int, str], ...], int]:\n    flags = re.UNICODE\n    if ftype in ('text', 'itext', 'regex', 'iregex'):\n        if ftype.startswith('i'):\n            flags |= re.IGNORECASE\n        if not parts or len(parts) % 2 != 0:\n            raise ValueError('Mark group number and text/regex are not specified in pairs: {}'.format(' '.join(parts)))\n        ans = []\n        for i in range(0, len(parts), 2):\n            try:\n                color = max(1, min(int(parts[i]), 3))\n            except Exception:\n                raise ValueError(f'Mark group in marker specification is not an integer: {parts[i]}')\n            sspec = parts[i + 1]\n            if 'regex' not in ftype:\n                sspec = re.escape(sspec)\n            ans.append((color, sspec))\n        ftype = 'regex'\n        spec: str | tuple[tuple[int, str], ...] = tuple(ans)\n    elif ftype == 'function':\n        spec = ' '.join(parts)\n    else:\n        raise ValueError(f'Unknown marker type: {ftype}')\n    return ftype, spec, flags\n\n\n@func_with_args('toggle_marker')\ndef toggle_marker(func: str, rest: str) -> FuncArgsType:\n    parts = rest.split(maxsplit=1)\n    if len(parts) != 2:\n        raise ValueError(f'{rest} is not a valid marker specification')","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/options/utils.py#L418-L454","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Make every group token a plain integer (it will be clamped to 1-3)","Order is: group number then pattern, repeated in pairs","Sanitize script-generated specs so group tokens are digits"],"exampleFix":"# before\nkitty @action set_marker text red ERROR\n# after\nkitty @action set_marker text 1 ERROR","handlingStrategy":"validation","validationCode":"for i in range(0, len(parts), 2):\n    if not parts[i].lstrip('-').isdigit():\n        raise SystemExit(f'group not an integer: {parts[i]}')","typeGuard":"def is_integer_group(tok: str) -> bool:\n    return tok.lstrip('-').isdigit() and int(tok) is not None","tryCatchPattern":"try:\n    group = int(tok)\nexcept ValueError:\n    group = 1  # clamp fallback","preventionTips":["Group tokens must be integers (clamped 1-3)","Order: group number first, then the text/regex pattern"],"tags":["kitty","markers","set-marker","type-coercion","action-args"],"backgroundTag":"argument-type-mismatch","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}