{"record":{"id":"f270d9b96df2b7a9","repo":"kovidgoyal/kitty","slug":"unknown-link-target-type","errorCode":null,"errorMessage":"Unknown link target type","messagePattern":"Unknown link target type","errorType":"exception","errorClass":"TransmissionError","httpStatus":null,"severity":"error","filePath":"kitty/file_transmission.py","lineNumber":537,"sourceCode":"            self.link_target += data\n            self.bytes_written += len(data)\n            if is_last:\n                lt = self.link_target.decode('utf-8', 'replace')\n                base = self.make_parent_dirs()\n                self.unlink_existing_if_needed(force=True)\n                if lt.startswith('fid:'):\n                    lt = all_files[lt[4:]].name\n                    if self.ftype is FileType.symlink:\n                        lt = os.path.relpath(lt, os.path.dirname(self.name))\n                elif lt.startswith('fid_abs:'):\n                    lt = all_files[lt[8:]].name\n                elif lt.startswith('path:'):\n                    lt = lt[5:]\n                    if not os.path.isabs(lt) and self.ftype is FileType.link:\n                        lt = os.path.join(base, lt)\n                    lt = lt.replace('/', os.sep)\n                else:\n                    raise TransmissionError(msg='Unknown link target type', file_id=self.file_id)\n                if self.ftype is FileType.symlink:\n                    os.symlink(lt, self.name)\n                else:\n                    os.link(lt, self.name)\n                self.close()\n                self.apply_metadata(is_symlink=True)\n        elif self.ftype is FileType.regular:\n            decompressed = self.decompressor(data, is_last=is_last)\n            if self.actual_file is None:\n                self.make_parent_dirs()\n                self.unlink_existing_if_needed()\n                flags = os.O_RDWR | os.O_CREAT | os.O_TRUNC | getattr(os, 'O_CLOEXEC', 0) | getattr(os, 'O_BINARY', 0) | getattr(os, 'O_NOFOLLOW', 0)\n                self.actual_file = open(os.open(self.name, flags, self.permissions), mode='r+b', closefd=True)\n            af = self.actual_file\n            if decompressed or is_last:\n                af.write(decompressed)\n                self.bytes_written = af.tell()\n            if is_last:","sourceCodeStart":519,"sourceCodeEnd":555,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/file_transmission.py#L519-L555","documentation":"For FileType.symlink/link entries, the accumulated link target must start with a scheme prefix ('file:', 'path:', etc.); an unrecognized prefix raises TransmissionError('Unknown link target type').","triggerScenarios":"write_data reaches is_last for a symlink/link DestFile whose decoded link_target does not start with any known prefix — sender used a raw target or an unsupported scheme.","commonSituations":"Custom senders writing bare paths as the target; protocol version drift adding/removing target schemes; hand-built test payloads.","solutions":["Prefix the target with a supported scheme, e.g. 'path:relative/path' or 'file:...'.","Align sender and receiver kitty versions so the supported prefix set matches."],"exampleFix":"# before\ntarget = b'/etc/hostname'\n# after\ntarget = b'path:/etc/hostname'","handlingStrategy":"validation","validationCode":"KNOWN_PREFIXES = ('file:', 'path:')\nassert any(target.startswith(p) for p in KNOWN_PREFIXES), target","typeGuard":"def is_valid_link_target(t: bytes) -> bool:\n    return any(t.startswith(p.encode()) for p in ('file:', 'path:'))","tryCatchPattern":"try:\n    link_entry.write_data(files, target, True)\nexcept TransmissionError as e:\n    if 'Unknown link target' in e.msg: fix_prefix_and_retry()\n    else: raise","preventionTips":["Always scheme-prefix link targets when building sequences.","Keep sender/receiver kitty versions matched."],"tags":["kitty","file-transfer","symlink","protocol"],"backgroundTag":"invalid-link-target","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}