denoland/deno · error

failed to capture HMR dev server stdout

Error message

failed to capture HMR dev server stdout

What it means

Internal invariant in the desktop dev flow: after spawning the HMR dev server with piped stdout, Deno takes the pipe handle to scan output for the startup URL. If the handle was already taken (or stdio wasn't actually piped), capture fails and the dev flow aborts immediately after a successful spawn.

Source

Thrown at cli/tools/desktop.rs:1212

  name: &str,
  cmd_args: &[String],
  cwd: &Path,
) -> Result<(String, tokio::process::Child), AnyError> {
  use tokio::io::AsyncBufReadExt;
  use tokio::io::BufReader;

  let mut child = tokio::process::Command::new(&cmd_args[0])
    .args(&cmd_args[1..])
    .current_dir(cwd)
    .stdout(std::process::Stdio::piped())
    .kill_on_drop(true)
    .spawn()
    .with_context(|| {
      format!("failed to spawn HMR dev server: {:?}", cmd_args)
    })?;

  let stdout = child.stdout.take().ok_or_else(|| {
    deno_core::anyhow::anyhow!("failed to capture HMR dev server stdout")
  })?;
  let mut lines = BufReader::new(stdout).lines();

  let url = tokio::time::timeout(std::time::Duration::from_secs(15), async {
    while let Ok(Some(line)) = lines.next_line().await {
      let url = parse_dev_server_url(&line);
      // Echo the dev server's own startup output (banner, URL, warnings) so
      // it isn't swallowed while we scan for the URL.
      log::info!("{line}");
      if let Some(url) = url {
        return Ok(url);
      }
    }
    deno_core::anyhow::bail!("dev server exited without printing a URL")
  })
  .await
  .map_err(|_| {
    deno_core::anyhow::anyhow!(

View on GitHub (pinned to f7822238ca)

Solutions

  1. Retry the desktop dev command — a transient spawn race is the likeliest cause
  2. Update deno; if it reproduces consistently, report with the exact command, platform, and deno version
Defensive patterns

Strategy: retry

Try / catch

Treat as transient: retry the desktop dev command once; if it fails identically, stop retrying and report with command, platform, and deno version.

Prevention

When it happens

Trigger: Only reachable through a deno bug or race in the desktop dev-server startup path — `stdout.take()` returning `None` right after a spawn configured with `.stdout(piped())` should be impossible.

Common situations: A race during process spawn on unusual platforms, or a regression in a specific deno version's desktop tooling.

Related errors


AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20). Data as JSON: /api/errors/efa2928d4b834da6. Report an issue: GitHub.