{"record":{"id":"f517588f0896232d","repo":"vi/websocat","slug":"assertion-failed-1425","errorCode":null,"errorMessage":"assertion failed 1425","messagePattern":"assertion failed 1425","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/process_peer.rs","lineNumber":207,"sourceCode":"    exit_on_disconnect: bool,\n}\n#[derive(Clone)]\nstruct ProcessPeer {\n    chld: Rc<RefCell<ForgetfulProcess>>,\n    sighup_on_zero: bool,\n    sighup_on_close: bool,\n}\n\nimpl Read for ProcessPeer {\n    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {\n        self.chld\n            .borrow_mut()\n            .chld\n            .as_mut()\n            .unwrap()\n            .stdout()\n            .as_mut()\n            .expect(\"assertion failed 1425\")\n            .read(buf)\n    }\n}\n\nimpl Write for ProcessPeer {\n    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {\n        #[cfg(unix)]\n        {\n            if self.sighup_on_zero && buf.is_empty() {\n                // TODO use nix crate?\n                if let Some(ref chld) = self.chld.borrow().chld {\n                    unsafe {\n                        extern crate libc;\n                        libc::kill(chld.id() as libc::pid_t, libc::SIGHUP);\n                    }\n                }\n            }\n        }","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/vi/websocat/blob/3a3574cd2f5d17857d87f3982e72c3ede159dde0/src/process_peer.rs#L189-L225","documentation":"This panic comes from .expect(\"assertion failed 1425\") on the child process stdout handle inside ProcessPeer::read. ProcessPeer keeps an Option<Child> whose stdout is only Some when the child was spawned with Stdio::piped(); the expect fires when stdout() returns None. It means the code tried to read from a child whose standard output was never captured or already taken.","triggerScenarios":"Creating a ProcessPeer for a child spawned without .stdout(Stdio::piped()), or after the child's stdout handle was already taken (take() on Child::stdout) and never put back.","commonSituations":"Configuring Command without piped stdout but assuming the peer wraps output; a spawn-time default (inherit/null) differing between environments or library versions; reading after another component (e.g. a logger) consumed the handle.","solutions":["When spawning the child, always set .stdout(Stdio::piped()) before creating the ProcessPeer.","Ensure nothing else calls Child::stdout().take() on the same child before ProcessPeer reads it.","Check the code that constructs ProcessPeer and make piped stdout a required precondition, failing fast at spawn time with a clear error instead of at read time."],"exampleFix":"// before\nlet child = Command::new(prog).spawn()?;\nlet peer = ProcessPeer::new(child);\npeer.read(buf)?; // panics: stdout not piped\n// after\nlet child = Command::new(prog)\n    .stdout(Stdio::piped())\n    .spawn()?;\nlet peer = ProcessPeer::new(child);\npeer.read(buf)?;","handlingStrategy":"validation","validationCode":"fn ensure_piped_stdout(cmd: &mut Command) -> &mut Command {\n    cmd.stdout(Stdio::piped())\n}\n// call before spawn and before constructing ProcessPeer","typeGuard":"fn child_stdout_available(child: &Child) -> bool {\n    // peek without taking: wrap child stdout in a field checked at construction\n    child.stdout.is_some()\n}","tryCatchPattern":"// panics cannot be caught in Rust (without catch_unwind); validate first\nlet peer = ProcessPeer::new(child);\nmatch peer.try_read(buf) {\n    Ok(n) => process(n),\n    Err(e) => eprintln!(\"child stdout unavailable: {}\", e),\n}","preventionTips":["Always spawn child processes with .stdout(Stdio::piped()) when output will be read.","Never call Child::stdout().take() outside the owning abstraction.","Validate stdio configuration right after spawn, before constructing the peer.","Make piped stdio a constructor requirement of ProcessPeer so misuse fails early."],"tags":["rust","panic","process","stdio"],"backgroundTag":"null-argument","analyzedSha":"3a3574cd2f5d17857d87f3982e72c3ede159dde0","analyzedAt":"2026-09-12T15:14:27.766Z","contentChangedAt":"2026-09-12T15:14:27.766Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}