{"record":{"id":"d18a5dc2800152b2","repo":"kovidgoyal/kitty","slug":"ignoring-osc-52-clipboard-write-request-as-it-is-n","errorCode":null,"errorMessage":"Ignoring OSC 52 clipboard write request as it is not valid base64. Error: {e}","messagePattern":"Ignoring OSC 52 clipboard write request as it is not valid base64\\. Error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/clipboard.py","lineNumber":514,"sourceCode":"            where = str(data, 'utf-8', 'replace')\n            data = data[len(data) :]\n        destinations = {ClipboardType.from_osc52_where_field(where) for where in where or 's0'}\n        destinations.discard(ClipboardType.unknown)\n        if len(data) == 1 and data.tobytes() == b'?':\n            for d in destinations:\n                rr = ReadRequest(is_primary_selection=d is ClipboardType.primary_selection)\n                self.handle_read_request(rr)\n        else:\n            for d in destinations:\n                wr = self.osc52_in_flight_write_requests.get(d)\n                if wr is None:\n                    wr = self.osc52_in_flight_write_requests[d] = WriteRequest(d is ClipboardType.primary_selection)\n                try:\n                    wr.add_base64_data(data)\n                except ValueError as e:\n                    # OSC 52 has no way to report errors to the client so just\n                    # discard the entire request\n                    log_error(f'Ignoring OSC 52 clipboard write request as it is not valid base64. Error: {e}')\n                if is_partial:\n                    return\n                self.osc52_in_flight_write_requests.pop(d, None)\n                if not wr.aborted:\n                    self.handle_write_request(wr)\n\n    def handle_write_request(self, wr: WriteRequest) -> None:\n        wr.flush_base64_data()\n        q = 'write-primary' if wr.is_primary_selection else 'write-clipboard'\n        allowed = q in get_options().clipboard_control\n        self.fulfill_write_request(wr, allowed)\n\n    def fulfill_write_request(self, wr: WriteRequest, allowed: bool = True) -> None:\n        wr.permission_pending = not allowed\n        if wr.protocol_type is ProtocolType.osc_52:\n            self.fulfill_legacy_write_request(wr, allowed)\n            return\n        cp = get_boss().primary_selection if wr.is_primary_selection else get_boss().clipboard","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/clipboard.py#L496-L532","documentation":"An OSC 52 clipboard write contained invalid base64; since OSC 52 has no error channel, kitty silently discards the entire request after logging.","triggerScenarios":"wr.add_base64_data(data) raises ValueError for illegal base64 characters or bad length in a legacy OSC 52 write.","commonSituations":"Shell scripts piping non-base64 into the 52 escape; remote apps through ssh with locale/encoding corruption; clipboard managers injecting bad data.","solutions":["Ensure only strict base64 goes between ESC ]52;c; and the terminator","Use `base64 -w0` (GNU) / `base64 | tr -d '\\n'` when building the payload","Prefer the kitty clipboard protocol (OSC 5522) which reports errors, for local clients"],"exampleFix":"# before\nprintf '\\033]52;c;%s\\a' \"$raw_text\"\n# after\nprintf '\\033]52;c;%s\\a' \"$(printf %s \"$raw_text\" | base64 | tr -d '\\n')\"","handlingStrategy":"try-catch","validationCode":"import base64\ntry:\n    base64.b64decode(b64_payload, validate=True)\nexcept Exception:\n    b64_payload = base64.b64encode(raw).decode()  # re-encode correctly","typeGuard":null,"tryCatchPattern":"try:\\n    base64.b64decode(data, validate=True)\\nexcept (ValueError, binascii.Error):\\n    drop_or_reencode()","preventionTips":["Strip newlines from base64 before embedding in OSC 52","Prefer OSC 5522 for clients that can receive errors"],"tags":["kitty","clipboard","osc52","base64"],"backgroundTag":"base64-decode-invalid-input","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}