{"record":{"id":"44e60cffa74e59ae","repo":"moghtech/komodo","slug":"pty-exited","errorCode":null,"errorMessage":"pty exited","messagePattern":"pty exited","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"info","filePath":"lib/transport/src/channel.rs","lineNumber":137,"sourceCode":"      .await\n  }\n\n  pub async fn send_terminal(\n    &self,\n    channel: Uuid,\n    data: anyhow::Result<Vec<u8>>,\n  ) -> anyhow::Result<()> {\n    self.send_message(TerminalMessage::new(channel, data)).await\n  }\n\n  pub async fn send_terminal_exited(\n    &self,\n    channel: Uuid,\n  ) -> anyhow::Result<()> {\n    self\n      .send_message(TerminalMessage::new(\n        channel,\n        Err(anyhow!(\"pty exited\")),\n      ))\n      .await\n  }\n}\n\n#[derive(Debug)]\npub struct Receiver<T> {\n  receiver: mpsc::Receiver<T>,\n  cancel: Option<CancellationToken>,\n}\n\nimpl<T: Send> Receiver<T> {\n  pub fn set_cancel(&mut self, cancel: CancellationToken) {\n    self.cancel = Some(cancel);\n  }\n\n  pub fn poll_recv(\n    &mut self,","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/moghtech/komodo/blob/780ac68b992094a9fccd5fffb760e0c84fd3c3d1/lib/transport/src/channel.rs#L119-L155","documentation":"send_terminal_exited sends a TerminalMessage carrying an Err(anyhow!(\"pty exited\")) to notify the remote side that the PTY backing the terminal channel has terminated. The message text is deliberately a sentinel value used to propagate the exit state through the normal message channel rather than a fault of the send itself.","triggerScenarios":"The library calls this (public) method when the pty process spawned for a terminal channel exits — the consumer receives a TerminalMessage whose payload is the error \"pty exited\" for the given channel UUID.","commonSituations":"User types `exit` in an attached shell; the shell crashes; the container/process behind the pty is killed; ssh exec channel terminates after command completion.","solutions":["Treat the received error as a normal end-of-session signal and close the terminal UI for that channel","Inspect the pty exit code at the source if you need to report why it exited","Do not attempt to keep sending terminal input to that channel UUID; request a new terminal if more interaction is needed","Render a friendly 'session ended' message to the end user instead of surfacing the raw error"],"exampleFix":"// before\nTerminalMessage::Err(e) => return Err(e),\n// after\nTerminalMessage::Err(e) if e.to_string() == \"pty exited\" => {\n  ui.close_terminal(channel); // normal session end\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match msg {\n  TerminalMessage::Err(e) if e.to_string() == \"pty exited\" => {\n    ui.show_session_ended(channel); // expected end-of-session\n  }\n  TerminalMessage::Err(e) => return Err(e),\n  TerminalMessage::Message(m) => ui.write(channel, &m),\n  _ => {}\n}","preventionTips":["Model pty exit as a normal terminal lifecycle event, not a crash","Capture and expose the pty exit code for better UX","Offer an easy way to spawn a new terminal channel after exit","Ignore stale input to a channel whose pty has exited"],"tags":["pty","terminal","process-exit","signaling"],"backgroundTag":"process-exited","analyzedSha":"780ac68b992094a9fccd5fffb760e0c84fd3c3d1","analyzedAt":"2026-09-08T10:02:44.861Z","contentChangedAt":"2026-09-08T10:02:44.861Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}