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 tempfileView on GitHub (pinned to 6d5d0c4406)
Solutions
- Make sure both ends of the connection run the same (or compatible) kitty version; restart the listening kitty instance after upgrading
- If writing a custom client, do not send a 'v' field or send v=0
- 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
- Pin both kitty ends to the same version
- Never inject a 'v' key into edit-protocol payloads unless implementing a newer spec
- Version-gate custom remote-control clients
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
- No stream_id in rc payload
- KITTY_PUBLIC_KEY has unknown version, if you are running on
- KITTY_PUBLIC_KEY has unknown version, if you are running on
- Ignoring encrypted rc command with unsupported protocol: {pc
- This should be run as kitten icat
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/35d47f8806783c9a.
Report an issue: GitHub.