sxyazi/yazi · warning

Terminal event stream closed during emulator detection

Error message

Terminal event stream closed during emulator detection

What it means

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.

Source

Thrown at yazi-emulator/src/probe.rs:87

		TERM.enter_raw_mode()?;
		let mut stream = EventStream::from(&*TERM);
		let mut rx = stream.take().unwrap();

		let result = async {
			let emulator = Self::from_env();
			emulator.request()?;

			loop {
				let wait_da1 = async {
					while let Some(event) = rx.recv().await {
						let Event::Report(report) = event? else { continue };

						emulator.apply(&report);
						if matches!(report, Report::Da1(_)) {
							return Ok(());
						}
					}
					bail!("Terminal event stream closed during emulator detection");
				};

				match time::timeout(Duration::from_secs(3), wait_da1).await {
					Ok(result) => result?,
					Err(_) => return Ok(emulator),
				}

				if !emulator.needs_passthrough() {
					return Ok(emulator);
				}

				Mux::tmux_setup().await;
				if let Err(e) = emulator.restart() {
					error!("Failed to request terminal capabilities through tmux: {e}");
					return Ok(emulator);
				}
			}
		}

View on GitHub (pinned to 5f901b886b)

Solutions

  1. Run in a real interactive terminal so the query/response handshake can complete.
  2. Avoid redirecting stdin from /dev/null or a pipe; provide a pty (e.g. use `script -c` or a pseudo-tty in wrappers).
  3. 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).

Example fix

// before
ya --version < /dev/null
// after
script -qec "ya --version" /dev/null  # allocate a pty for detection
Defensive patterns

Strategy: fallback

Try / catch

match probe().await {
    Ok(emulator) => emulator,
    Err(e) if e.to_string().contains("stream closed") => Emulator::default(), // non-tty environment
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/c516d01098c75a69. Report an issue: GitHub.