kovidgoyal/kitty · error · ValueError

Incorrect request id: {rq_id!r} expecting the KITTY_PID-KITT

Error message

Incorrect request id: {rq_id!r} expecting the KITTY_PID-KITTY_WINDOW_ID for the current kitty window

What it means

get_ssh_data() validates that the request id (rq_id) parsed from the incoming request equals the request_id it computed for the current connection, which is derived from KITTY_PID-KITTY_WINDOW_ID of the current kitty window. A mismatch raises ValueError('Incorrect request id: ...'); the handler catches it, prints the traceback, and yields a regex-sanitized error message back to the requester.

Source

Thrown at kittens/ssh/utils.py:197

    from base64 import standard_b64decode

    yield b'\nKITTY_DATA_START\n'  # to discard leading data
    try:
        msg = standard_b64decode(msgb).decode('utf-8')
        md = dict(x.split('=', 1) for x in msg.split(':'))
        pw = md['pw']
        pwfilename = md['pwfile']
        rq_id = md['id']
    except Exception:
        traceback.print_exc()
        yield b'invalid ssh data request message\n'
    else:
        try:
            env_data = read_data_from_shared_memory(pwfilename)
            if pw != env_data['pw']:
                raise ValueError('Incorrect password')
            if rq_id != request_id:
                raise ValueError(f'Incorrect request id: {rq_id!r} expecting the KITTY_PID-KITTY_WINDOW_ID for the current kitty window')
        except Exception as e:
            traceback.print_exc()
            import re

            msg = re.sub(r'[^a-zA-Z0-9 ]+', '_', str(e))
            yield f'{msg}\n'.encode()
        else:
            yield b'OK\n'
            encoded_data = memoryview(env_data['tarfile'].encode('ascii'))
            # macOS has a 255 byte limit on its input queue as per man stty.
            # Not clear if that applies to canonical mode input as well, but
            # better to be safe.
            line_sz = 254
            while encoded_data:
                yield encoded_data[:line_sz]
                yield b'\n'
                encoded_data = encoded_data[line_sz:]
            yield b'KITTY_DATA_END\n'

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Re-run the ssh command from the current kitty window so KITTY_PID-KITTY_WINDOW_ID match the live window.
  2. unset/sanitize exported KITTY_PID and KITTY_WINDOW_ID in shells that outlive their kitty window (add to shell rc hygiene).
  3. Restart the remote ssh kitten wrapper if kitty restarted mid-session; the old ids are permanently invalid.
  4. If scripting the protocol, derive request_id from the current window's env, never hardcode it.

Example fix

# before (stale env in a long-lived shell)
export KITTY_PID=1234 KITTY_WINDOW_ID=2  # kitty restarted, PID is gone
kitten ssh host  # -> Incorrect request id

# after
unset KITTY_PID KITTY_WINDOW_ID
# open a fresh kitty window and run kitten ssh host there
Defensive patterns

Strategy: validation

Validate before calling

import os

def current_request_id() -> str | None:
    pid, wid = os.environ.get('KITTY_PID'), os.environ.get('KITTY_WINDOW_ID')
    if not pid or not wid:
        return None  # not inside a live kitty window; don't attempt the handshake
    return f'{pid}-{wid}'

# only proceed when this matches the id the pwfile was created with

Try / catch

try:
    ...  # perform ssh data request
except Exception as e:
    if 'Incorrect request id' in str(e):
        refresh_kitty_env_or_restart_session()  # stale KITTY_PID/KITTY_WINDOW_ID
    else:
        raise

Prevention

When it happens

Trigger: handle_remote_ssh() or a hand-rolled client sends a request whose rq_id isn't the KITTY_PID-KITTY_WINDOW_ID of the window that owns the pwfile — e.g. after kitty restarted (new PID) while a remote ssh wrapper still had the old id, multiple windows sharing shm state, or a manually crafted request message.

Common situations: kitty was restarted or the window closed/reopened during a remote ssh kitten session; KITTY_PID/KITTY_WINDOW_ID env vars exported into a different shell/session and reused; scripts shelling the ssh kitten protocol from outside kitty; tmux/screen inside kitty propagating stale kitty env vars to a later session.

Related errors


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