kovidgoyal/kitty · warning

Malformed OSC 5522: could not decode a metadata value. Error

Error message

Malformed OSC 5522: could not decode a metadata value. Error: {e}

What it means

OSC 5522 metadata keys decoded but a metadata value failed decode_metadata_value (e.g. non-UTF8 after strict base64). If it belonged to an in-flight write request, that request is aborted with EINVAL back to the client.

Source

Thrown at kitty/clipboard.py:406

        if idx > -1:
            metadata = str(data[:idx], 'utf-8', 'replace')
            epayload = data[idx + 1 :]
        else:
            metadata = str(data, 'utf-8', 'replace')
            epayload = data[len(data) :]
        m: dict[str, str] = {}
        for record in metadata.split(':'):
            try:
                k, v = record.split('=', 1)
            except Exception:
                log_error('Malformed OSC 5522: metadata is not key=value pairs')
                return
            m[k] = v
        typ = m.get('type', '')
        try:
            m = {k: decode_metadata_value(k, v) for k, v in m.items()}
        except Exception as e:
            log_error(f'Malformed OSC 5522: could not decode a metadata value. Error: {e}')
            if typ in ('wdata', 'walias') and self.in_flight_write_request is not None:
                self.abort_write_request(self.in_flight_write_request, 'EINVAL')
            return
        if typ == 'read':
            try:
                mime_types = tuple(strict_base64_decode(epayload).decode('utf-8').split())
            except Exception as e:
                log_error(f'Malformed OSC 5522: read request payload is not valid base64 encoded UTF-8. Error: {e}')
                return
            rr = ReadRequest(
                is_primary_selection=m.get('loc', '') == 'primary',
                mime_types=mime_types,
                protocol_type=ProtocolType.osc_5522,
                id=sanitize_id(m.get('id', '')),
                human_name=m.get('name', ''),
                password=m.get('pw', ''),
            )
            self.handle_read_request(rr)

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Match the kitty version's clipboard protocol docs when encoding metadata
  2. Re-encode values as base64(UTF-8)
  3. Update kitty / the client app so both speak the same protocol version
Defensive patterns

Strategy: validation

Validate before calling

import base64
def dec_meta(v: str) -> bool:
    try:
        base64.b64decode(v, validate=True).decode('utf-8')
        return True
    except Exception:
        return False

Prevention

When it happens

Trigger: Client sends a metadata value whose base64 does not decode to UTF-8 text, or uses an unexpected value format for a known key.

Common situations: Version mismatch: client implements an older/newer OSC 5522 metadata encoding than kitty expects; hand-built test payloads.

Understand the failure class

Related errors


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