kovidgoyal/kitty · warning

Ignoring OSC 52 clipboard write request as it is not valid b

Error message

Ignoring OSC 52 clipboard write request as it is not valid base64. Error: {e}

What it means

An OSC 52 clipboard write contained invalid base64; since OSC 52 has no error channel, kitty silently discards the entire request after logging.

Source

Thrown at kitty/clipboard.py:514

            where = str(data, 'utf-8', 'replace')
            data = data[len(data) :]
        destinations = {ClipboardType.from_osc52_where_field(where) for where in where or 's0'}
        destinations.discard(ClipboardType.unknown)
        if len(data) == 1 and data.tobytes() == b'?':
            for d in destinations:
                rr = ReadRequest(is_primary_selection=d is ClipboardType.primary_selection)
                self.handle_read_request(rr)
        else:
            for d in destinations:
                wr = self.osc52_in_flight_write_requests.get(d)
                if wr is None:
                    wr = self.osc52_in_flight_write_requests[d] = WriteRequest(d is ClipboardType.primary_selection)
                try:
                    wr.add_base64_data(data)
                except ValueError as e:
                    # OSC 52 has no way to report errors to the client so just
                    # discard the entire request
                    log_error(f'Ignoring OSC 52 clipboard write request as it is not valid base64. Error: {e}')
                if is_partial:
                    return
                self.osc52_in_flight_write_requests.pop(d, None)
                if not wr.aborted:
                    self.handle_write_request(wr)

    def handle_write_request(self, wr: WriteRequest) -> None:
        wr.flush_base64_data()
        q = 'write-primary' if wr.is_primary_selection else 'write-clipboard'
        allowed = q in get_options().clipboard_control
        self.fulfill_write_request(wr, allowed)

    def fulfill_write_request(self, wr: WriteRequest, allowed: bool = True) -> None:
        wr.permission_pending = not allowed
        if wr.protocol_type is ProtocolType.osc_52:
            self.fulfill_legacy_write_request(wr, allowed)
            return
        cp = get_boss().primary_selection if wr.is_primary_selection else get_boss().clipboard

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Ensure only strict base64 goes between ESC ]52;c; and the terminator
  2. Use `base64 -w0` (GNU) / `base64 | tr -d '\n'` when building the payload
  3. Prefer the kitty clipboard protocol (OSC 5522) which reports errors, for local clients

Example fix

# before
printf '\033]52;c;%s\a' "$raw_text"
# after
printf '\033]52;c;%s\a' "$(printf %s "$raw_text" | base64 | tr -d '\n')"
Defensive patterns

Strategy: try-catch

Validate before calling

import base64
try:
    base64.b64decode(b64_payload, validate=True)
except Exception:
    b64_payload = base64.b64encode(raw).decode()  # re-encode correctly

Try / catch

try:\n    base64.b64decode(data, validate=True)\nexcept (ValueError, binascii.Error):\n    drop_or_reencode()

Prevention

When it happens

Trigger: wr.add_base64_data(data) raises ValueError for illegal base64 characters or bad length in a legacy OSC 52 write.

Common situations: Shell scripts piping non-base64 into the 52 escape; remote apps through ssh with locale/encoding corruption; clipboard managers injecting bad data.

Related errors


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