{"record":{"id":"87cba03dfe5f5e50","repo":"EpicGames/lore","slug":"pager-process-stdin-not-available","errorCode":null,"errorMessage":"Pager process stdin not available","messagePattern":"Pager process stdin not available","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"lore-client/src/cli/pager.rs","lineNumber":88,"sourceCode":"        } else {\n            let config = config();\n            let mut pager_config = config.pager.split_ascii_whitespace();\n            if let Some(pager_target) = pager_config.next() {\n                let mut cmd = Command::new(pager_target);\n                cmd.args(pager_config);\n                Some(cmd)\n            } else {\n                None\n            }\n            .and_then(|mut cmd| cmd.stdin(Stdio::piped()).spawn().ok())\n        };\n\n        child.map(|child| PagerProcess { child })\n    }\n\n    fn stdin(&self) -> std::io::Result<&ChildStdin> {\n        match &self.child.stdin {\n            None => Err(std::io::Error::new(\n                std::io::ErrorKind::NotFound,\n                \"Pager process stdin not available\",\n            )),\n            Some(stdin) => Ok(stdin),\n        }\n    }\n}\n\nimpl Write for PagerProcess {\n    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {\n        self.stdin()?.write(buf)\n    }\n\n    fn flush(&mut self) -> std::io::Result<()> {\n        self.stdin()?.flush()\n    }\n}\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/EpicGames/lore/blob/074eb0b0d1194c997d7cf28b55519e3e197b3e23/lore-client/src/cli/pager.rs#L70-L106","documentation":"`PagerProcess::stdin` returns this io::Error (ErrorKind::NotFound) when the pager child process has no piped stdin. `PagerProcess::new` only spawns a pager when stdout is a terminal and a pager command is configured and spawnable; otherwise the PagerProcess is created without a usable stdin, and any `write`/`flush` (via the `Write` impl) or direct `stdin()` call fails.","triggerScenarios":"Calling `write` or `flush` on a `PagerProcess` (or `stdin()` directly) after the pager was created without piped stdin — i.e. stdout was not a terminal, the configured pager string was empty, or `Command::spawn` failed so no child with piped stdin exists.","commonSituations":"Running a lore-client command with output piped to another process or to a file (stdout not a TTY), so no pager is spawned but code still writes to the pager; an invalid or missing pager binary in the config's `pager` setting so spawn silently failed.","solutions":["Check whether output is going to a terminal (e.g. `stdout().is_terminal()`) and fall back to writing to plain stdout instead of the pager when it is not.","Verify the `pager` setting in the client config names an installed pager binary (e.g. `less`); an empty or broken value leaves no stdin.","Handle the write error gracefully by writing to a backup stream (use `Pager::with_backup_stream`)."],"exampleFix":"// before\npager.write_all(output)?;  // fails when no pager spawned\n// after\nif stdout().is_terminal() {\n    pager.write_all(output)?;\n} else {\n    stdout().write_all(output)?;\n}","handlingStrategy":"fallback","validationCode":"// Rust: only use the pager when stdout is a terminal and a pager command is configured\nlet use_pager = std::io::stdout().is_terminal()\n    && config.pager.split_ascii_whitespace().next().is_some();","typeGuard":null,"tryCatchPattern":"// Rust\nuse std::io::Write;\nmatch pager.write_all(bytes) {\n    Err(e) if e.kind() == std::io::ErrorKind::NotFound => {\n        // pager has no stdin (no TTY / spawn failed): write to backup stream\n        backup.write_all(bytes)?;\n    }\n    r => r?,\n}","preventionTips":["Always construct the pager via `Pager::with_backup_stream` so failed pager writes go to plain output.","Check `stdout().is_terminal()` before instantiating the pager.","Validate the configured pager command exists (e.g. `which $PAGER`) in diagnostics."],"tags":["io","cli","pager","process"],"backgroundTag":"file-not-found","analyzedSha":"074eb0b0d1194c997d7cf28b55519e3e197b3e23","analyzedAt":"2026-09-13T09:00:57.509Z","contentChangedAt":"2026-09-13T09:00:57.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}