{"record":{"id":"5690523c2b6565f0","repo":"kovidgoyal/kitty","slug":"invalid-listen-on-value-spec-must-be-of-the-for","errorCode":null,"errorMessage":"Invalid listen-on value: {spec} must be of the form protocol:address","messagePattern":"Invalid listen-on value: (.+?) must be of the form protocol:address","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kitty/utils.py","lineNumber":391,"sourceCode":"    for loc in candidates:\n        if os.access(loc, os.W_OK | os.R_OK | os.X_OK):\n            yield loc\n\n\ndef unix_socket_paths(name: str, ext: str = '.lock') -> Generator[str, None, None]:\n    home = os.path.expanduser('~')\n    for loc in unix_socket_directories():\n        filename = ('.' if loc == home else '') + name + ext\n        yield os.path.join(loc, filename)\n\n\ndef parse_address_spec(spec: str) -> tuple[AddressFamily, tuple[str, int] | str, str | None]:\n    import socket\n\n    try:\n        protocol, rest = spec.split(':', 1)\n    except ValueError:\n        raise ValueError(f'Invalid listen-on value: {spec} must be of the form protocol:address')\n    socket_path = None\n    address: str | tuple[str, int] = ''\n    if protocol == 'unix':\n        family = socket.AF_UNIX\n        address = rest\n        if address.startswith('@') and len(address) > 1:\n            address = '\\0' + address[1:]\n        else:\n            socket_path = address\n    elif protocol in ('tcp', 'tcp6'):\n        family = socket.AF_INET if protocol == 'tcp' else socket.AF_INET6\n        if rest.startswith('['):  # ]\n            host = rest[1:]\n            host, sep, leftover = host.rpartition(']')\n            _, port = leftover.rsplit(':', 1)\n            if ':' in host and protocol == 'tcp':\n                family = socket.AF_INET6\n        else:","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/utils.py#L373-L409","documentation":"parse_address_spec() requires a listen-on string of the form 'protocol:address'; when the spec contains no ':' at all, spec.split(':', 1) raises ValueError, which is re-raised with this clearer message. Valid protocols are 'unix:' and 'tcp:'.","triggerScenarios":"--listen-on=9901 (bare port), --listen-on=localhost (no protocol), or any spec without a colon.","commonSituations":"Mistaking kitty's syntax for other tools' listen formats (e.g. 'host:port' without 'tcp:'); typos in kitty.conf's listen_on directive; script-generated configs dropping the protocol prefix.","solutions":["Use unix:/path/to/socket or tcp:host:port (e.g. tcp:localhost:9901)","Validate the spec contains a colon before passing it","If generating kitty.conf programmatically, assert the format in your generator"],"exampleFix":"# before\nkitty --listen-on=/tmp/kitty-sock\n# after\nkitty --listen-on=unix:/tmp/kitty-sock","handlingStrategy":"validation","validationCode":"def valid_address_spec(spec: str) -> bool:\n    return ':' in spec","typeGuard":null,"tryCatchPattern":"try:\n    fam, addr, path = parse_address_spec(spec)\nexcept ValueError as e:\n    if 'Invalid listen-on value' in str(e):\n        spec = f'unix:{default_socket}'\n        fam, addr, path = parse_address_spec(spec)\n    else:\n        raise","preventionTips":["Always write listen-on as protocol:address (unix:/path or tcp:host:port)","Validate config strings before launching kitty from scripts"],"tags":["configuration","listen-on","address-parsing"],"backgroundTag":"invalid-listen-address","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}