{"record":{"id":"f43a9249dea3f41c","repo":"kovidgoyal/kitty","slug":"no-stream-id-in-rc-payload","errorCode":null,"errorMessage":"No stream_id in rc payload","messagePattern":"No stream_id in rc payload","errorType":"exception","errorClass":"StreamError","httpStatus":null,"severity":"error","filePath":"kitty/rc/base.py","lineNumber":440,"sourceCode":"                    windows += list(tab)\n        return windows\n\n    def create_async_responder(self, payload_get: PayloadGetType, window: Window | None) -> AsyncResponder:\n        return AsyncResponder(payload_get, window)\n\n    def message_to_kitty(self, global_opts: RCOptions, opts: Any, args: ArgsType) -> PayloadType:\n        raise NotImplementedError()\n\n    def response_from_kitty(self, boss: 'Boss', window: Optional['Window'], payload_get: PayloadGetType) -> ResponseType:\n        raise NotImplementedError()\n\n    def cancel_async_request(self, boss: 'Boss', window: Optional['Window'], payload_get: PayloadGetType) -> None:\n        pass\n\n    def handle_streamed_data(self, data: bytes, payload_get: PayloadGetType) -> BytesIO | AsyncResponse:\n        stream_id = payload_get('stream_id')\n        if not stream_id or not isinstance(stream_id, str):\n            raise StreamError('No stream_id in rc payload')\n        return self.stream_in_flight.handle_data(stream_id, data)\n\n\ndef cli_params_for(command: RemoteCommand) -> tuple[Callable[[], str], str, str, str]:\n    return (command.options_spec or '\\n').format, command.args.spec, command.desc, f'kitten @ {command.name}'\n\n\ndef parse_subcommand_cli(command: RemoteCommand, args: ArgsType) -> tuple[Any, ArgsType]:\n    opts, items = parse_args(args[1:], *cli_params_for(command), result_class=command.options_class)\n    if command.args.args_count is not None and command.args.args_count != len(items):\n        if command.args.args_count == 0:\n            raise SystemExit(f'Unknown extra argument(s) supplied to {command.name}')\n        raise SystemExit(f'Must specify exactly {command.args.args_count} argument(s) for {command.name}')\n    return opts, items\n\n\ndef display_subcommand_help(func: RemoteCommand) -> None:\n    with suppress(SystemExit):","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/rc/base.py#L422-L458","documentation":"StreamError from kitty's remote-control streaming layer when a streamed data payload lacks a valid 'stream_id' string. stream_id correlates chunks with the in-flight stream started by a prior ESC @ stream-control sequence; without it the data cannot be routed and the command is rejected.","triggerScenarios":"Calling handle_streamed_data with a payload whose stream_id is missing, empty, or not a string — e.g. hand-crafted escape sequences for remote control streaming that skip the stream_id field, or a client library that drops the key during JSON serialization.","commonSituations":"Writing a custom remote-control client, protocol-level scripts emitting kitty escape codes, or version mismatches where the client omits the newer stream_id field.","solutions":["When starting a stream, capture the stream_id from the initial response and include it in every subsequent data payload","Verify the payload key is exactly 'stream_id' and is a non-empty string","Prefer using 'kitten @ ...' CLI or the kittens RPC helpers rather than hand-rolling the streaming protocol"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"sid = payload.get('stream_id')\nif not isinstance(sid, str) or not sid:\n    raise ValueError('cannot stream without a stream_id from the initial stream-open response')\nsend_stream_chunk(sid, data)","typeGuard":"def has_stream_id(payload: dict) -> bool:\n    sid = payload.get('stream_id')\n    return isinstance(sid, str) and len(sid) > 0","tryCatchPattern":"try:\n    conn.handle_streamed_data(data, payload_get)\nexcept StreamError as e:\n    if 'No stream_id' in str(e):\n        reopen_stream()  # re-negotiate stream and resend with fresh id\n    else:\n        raise","preventionTips":["Always store the stream_id from the stream-open response and attach it to every chunk","Use kitty's own client helpers instead of hand-crafting streaming escape sequences"],"tags":["kitty","remote-control","streaming","protocol"],"backgroundTag":"missing-stream-identifier","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}