kovidgoyal/kitty · error · ValueError

Unsupported version received in edit protocol: {self.version

Error message

Unsupported version received in edit protocol: {self.version}

What it means

Raised by the edit/clone protocol kitten when the version number sent by the remote peer is greater than 0 (this build only speaks version 0 of the protocol). It is a protocol-negotiation failure: the value arrived in the message payload (e.g. via a 'v' key parsed as an integer), so the other side is newer or speaking a different protocol.

Source

Thrown at kitty/launch.py:1021

        for k, v in parse_message(msg, simple):
            if k == 'file_inode':
                q = map(int, v.split(':'))
                self.file_inode = next(q), next(q)
                self.file_size = next(q)
            elif k == 'a':
                self.args.append(v)
            elif k == 'file_data':
                import base64

                self.file_data = base64.standard_b64decode(v)
            elif k == 'version':
                self.version = int(v)
            else:
                setattr(self, k, v)
        if self.abort_signaled:
            return
        if self.version > 0:
            raise ValueError(f'Unsupported version received in edit protocol: {self.version}')
        self.opts, extra_args = parse_opts_for_clone(['--type=overlay'] + self.args)
        self.file_spec = extra_args.pop()
        self.line_number = 0
        import re

        pat = re.compile(r'\+(-?\d+)')
        for x in extra_args:
            m = pat.match(x)
            if m is not None:
                self.line_number = int(m.group(1))
        self.file_name = os.path.basename(self.file_spec)
        self.file_localpath = os.path.normpath(os.path.join(self.cwd, self.file_spec))
        self.is_local_file = False
        with suppress(OSError):
            st = os.stat(self.file_localpath)
            self.is_local_file = (st.st_dev, st.st_ino) == self.file_inode and os.access(self.file_localpath, os.W_OK | os.R_OK)
        if not self.is_local_file:
            import tempfile

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Make sure both ends of the connection run the same (or compatible) kitty version; restart the listening kitty instance after upgrading
  2. If writing a custom client, do not send a 'v' field or send v=0
  3. Check that the message payload only contains keys this protocol version defines

Example fix

// before
payload = {'v': 1, 'args': [...], 'file': 'f.txt'}
// after
payload = {'args': [...], 'file': 'f.txt'}
Defensive patterns

Strategy: validation

Validate before calling

version = payload.get('v', 0)
if not isinstance(version, int) or version > 0:
    raise ValueError('peer speaks unsupported edit protocol version')

Try / catch

try:
    req = CloneRequest.parse(payload)
except ValueError as e:
    log.warning('edit protocol handshake failed: %s', e)
    reconnect_with_matching_version()

Prevention

When it happens

Trigger: Calling the kitten (e.g. kitty @ launch --type=overlay clone or the hints/scrollback 'edit in kitty' flow) against a kitty instance or remote-control message that includes a protocol version > 0; also any custom client that sends {"v": 1, ...}.

Common situations: Mixing kitty versions (newer kitty client talking to older kitty server, or vice versa), or a hand-rolled remote-control script that adds a version field. Upgrading one side of a socket/ssh setup without the other.

Related errors


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