denoland/deno · error
dev server with HMR did not start within 15s
Error message
{name} dev server with HMR did not start within 15s What it means
The desktop dev flow spawns the framework's HMR dev server and waits up to 15 seconds for it to print a URL, parsing each stdout line. If no URL appears within the window — server slow to boot, crashed, or printing a URL in an unrecognized format — this timeout fires. The server's echoed startup output appears in the log above the error.
Solutions
- Run the dev server manually with the same command (visible in the echoed log lines) to see the real startup error
- Pre-install dependencies so the 15s window isn't spent resolving, and free the expected port
- Free up CPU/disk — slow cold starts are the most common cause
- If the server does print a URL but in a custom format, restore the default banner or report a parsing issue
Defensive patterns
Strategy: retry
Validate before calling
// Preflight: ensure the dev port is free and deps are installed
const port = 5173;
const conn = await Deno.connect({ port }).catch(() => null);
if (conn) {
conn.close();
throw new Error(`port ${port} already in use — stop the other dev server`);
}
try {
await Deno.stat("node_modules");
} catch {
throw new Error("dependencies not installed — run the install step first");
} Try / catch
Catch the timeout, echo the captured startup log to identify the real cause (crash, slow boot, unrecognized URL format), fix that, then retry — don't just extend waiting blindly.
Prevention
- Install dependencies before the first dev run
- Keep the framework's default startup banner so the URL stays parseable
- Reserve the dev-server port and keep CI runners warm for cold-start-heavy projects
When it happens
Trigger: Dev server takes more than 15s to first URL print (cold dependency install, huge project, slow disk), crashes on startup (port in use, invalid framework config), or its banner is customized so the URL line no longer matches Deno's parser.
Common situations: First run before dependencies are installed; port conflicts from an already-running dev server; resource-starved CI machines; frameworks with custom startup banners.
Related errors
- dev server exited without printing a URL
- failed to capture HMR dev server stdout
- icon ' ' must be .icns or .png
- icon ' ' not found
- icon sets are not supported in --hmr mode yet
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/3e3edf41d4a64536.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/desktop.rs:1230
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!(
"{name} dev server with HMR did not start within 15s"
)
})??;
// Keep forwarding the dev server's stdout so its HMR/compile logs stay
// visible after startup instead of being silently swallowed. The task ends
// on its own once the child is killed (on drop) and the pipe closes.
tokio::spawn(async move {
while let Ok(Some(line)) = lines.next_line().await {
log::info!("{line}");
}
});
Ok((url, child))
}
/// Launch the desktop app with HMR enabled after compilation.
///View on GitHub (pinned to f7822238ca)