{"record":{"id":"c516d01098c75a69","repo":"sxyazi/yazi","slug":"terminal-event-stream-closed-during-emulator-detec","errorCode":null,"errorMessage":"Terminal event stream closed during emulator detection","messagePattern":"Terminal event stream closed during emulator detection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"yazi-emulator/src/probe.rs","lineNumber":87,"sourceCode":"\t\tTERM.enter_raw_mode()?;\n\t\tlet mut stream = EventStream::from(&*TERM);\n\t\tlet mut rx = stream.take().unwrap();\n\n\t\tlet result = async {\n\t\t\tlet emulator = Self::from_env();\n\t\t\temulator.request()?;\n\n\t\t\tloop {\n\t\t\t\tlet wait_da1 = async {\n\t\t\t\t\twhile let Some(event) = rx.recv().await {\n\t\t\t\t\t\tlet Event::Report(report) = event? else { continue };\n\n\t\t\t\t\t\temulator.apply(&report);\n\t\t\t\t\t\tif matches!(report, Report::Da1(_)) {\n\t\t\t\t\t\t\treturn Ok(());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbail!(\"Terminal event stream closed during emulator detection\");\n\t\t\t\t};\n\n\t\t\t\tmatch time::timeout(Duration::from_secs(3), wait_da1).await {\n\t\t\t\t\tOk(result) => result?,\n\t\t\t\t\tErr(_) => return Ok(emulator),\n\t\t\t\t}\n\n\t\t\t\tif !emulator.needs_passthrough() {\n\t\t\t\t\treturn Ok(emulator);\n\t\t\t\t}\n\n\t\t\t\tMux::tmux_setup().await;\n\t\t\t\tif let Err(e) = emulator.restart() {\n\t\t\t\t\terror!(\"Failed to request terminal capabilities through tmux: {e}\");\n\t\t\t\t\treturn Ok(emulator);\n\t\t\t\t}\n\t\t\t}\n\t\t}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/sxyazi/yazi/blob/5f901b886b14de1f17460b6e52e9de5d67f8aba9/yazi-emulator/src/probe.rs#L69-L105","documentation":"During emulator detection (yazi-emulator/src/probe.rs:87), the probe writes terminal queries (DA1, OSC reports) and awaits responses with a 3-second timeout. If the terminal's event/input stream closes (EOF) before a DA1 report arrives, the inner future bails with this message, aborting detection since no more reports can ever arrive.","triggerScenarios":"Running `probe` when stdin/tty input reaches EOF mid-handshake — e.g. the terminal was closed, the process's stdin was redirected/piped from a file, or running under a non-interactive wrapper that closes the pty.","commonSituations":"Running yazi/ya under CI, inside a script with `</dev/null`, over SSH with a dying connection, or within test harnesses that don't provide a real pty.","solutions":["Run in a real interactive terminal so the query/response handshake can complete.","Avoid redirecting stdin from /dev/null or a pipe; provide a pty (e.g. use `script -c` or a pseudo-tty in wrappers).","Treat this as a non-fatal condition upstream: fall back to the default emulator profile instead of failing (note the timeout path already returns Ok with partial results)."],"exampleFix":"// before\nya --version < /dev/null\n// after\nscript -qec \"ya --version\" /dev/null  # allocate a pty for detection","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match probe().await {\n    Ok(emulator) => emulator,\n    Err(e) if e.to_string().contains(\"stream closed\") => Emulator::default(), // non-tty environment\n    Err(e) => return Err(e),\n}","preventionTips":["Run under a real pty; avoid `</dev/null` and closed-stdin wrappers.","In CI or scripts, use `script -qec` or a pty library when invoking yazi/ya.","Treat detection failure as 'unknown terminal' and use default capabilities."],"tags":["terminal","emulator-detection","eof","tty"],"backgroundTag":"terminal-stream-closed","analyzedSha":"5f901b886b14de1f17460b6e52e9de5d67f8aba9","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}