{"record":{"id":"cf6af63945cdd58b","repo":"kovidgoyal/kitty","slug":"x-is-not-a-unicode-codepoint-of-the-form-u-numbe","errorCode":null,"errorMessage":"{x} is not a unicode codepoint of the form U+number","messagePattern":"(.+?) is not a unicode codepoint of the form U\\+number","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kitty/options/utils.py","lineNumber":1225,"sourceCode":"    parts = val.split(maxsplit=1)\n    if len(parts) > 1:\n        alias_name, rest = parts\n        yield alias_name, rest\n\n\nkitten_alias = action_alias\n\n\ndef symbol_map_parser(val: str, min_size: int = 2) -> Iterable[tuple[tuple[int, int], str]]:\n    parts = val.split()\n\n    if len(parts) < min_size:\n        raise ValueError('must have codepoints AND font name')\n    family = ' '.join(parts[1:])\n\n    def to_chr(x: str) -> int:\n        if not x.startswith('U+'):\n            raise ValueError(f'{x} is not a unicode codepoint of the form U+number')\n        return int(x[2:], 16)\n\n    for x in parts[0].split(','):\n        a_, b_ = x.replace('–', '-').partition('-')[::2]\n        b_ = b_ or a_\n        a, b = map(to_chr, (a_, b_))\n        if b < a or max(a, b) > sys.maxunicode or min(a, b) < 1:\n            raise ValueError(f'Invalid range: {a:x} - {b:x}')\n        yield (a, b), family\n\n\ndef symbol_map(val: str) -> Iterable[tuple[tuple[int, int], str]]:\n    yield from symbol_map_parser(val)\n\n\ndef narrow_symbols(val: str) -> Iterable[tuple[tuple[int, int], int]]:\n    for x, y in symbol_map_parser(val, min_size=1):\n        yield x, int(y or 1)","sourceCodeStart":1207,"sourceCodeEnd":1243,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/options/utils.py#L1207-L1243","documentation":"Each codepoint in a symbol_map range must start with 'U+' followed by hexadecimal digits; to_chr rejects anything else with this message.","triggerScenarios":"Codepoints written as 'e0a0', '0xE0A0', 'U+E0A0-U+E0A2' with a malformed endpoint, or non-hex characters after U+.","commonSituations":"Copy/pasting font docs that use 0x... notation, typos like U+E0AG, or en-dash ranges where one side is empty.","solutions":["Write codepoints as U+hex, e.g. U+E0A0","Fix any malformed endpoints in ranges (both sides of the dash)"],"exampleFix":"# before\nsymbol_map 0xE0A0 Nerd Font\n# after\nsymbol_map U+E0A0 Nerd Font","handlingStrategy":"validation","validationCode":"import re\ndef valid_codepoints(spec: str) -> bool:\n    return all(re.fullmatch(r'[0-9a-fA-F]+', p[2:]) for x in spec.split(',') for p in x.replace('\\u2013','-').partition('-')[::2] if p.startswith('U+'))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Write codepoints as U+hex"],"tags":["kitty","config","unicode","symbol-map"],"backgroundTag":"invalid-codepoint-format","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}