From b13cc5c2b96fcf88817d14d06e931cae5f017e37 Mon Sep 17 00:00:00 2001 From: ciregenz Date: Wed, 10 Jun 2026 01:35:12 -0700 Subject: [PATCH] [eric] outputs: gate preview URL on a live runtime, a crashed vite no longer hands the webview a dead port (ERR_FAILED on reopen) --- backend/apps/outputs/runtime.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/backend/apps/outputs/runtime.py b/backend/apps/outputs/runtime.py index 4251e2ce..e9d88b08 100644 --- a/backend/apps/outputs/runtime.py +++ b/backend/apps/outputs/runtime.py @@ -127,7 +127,10 @@ class AppRuntime: # over once Vite is actually accepting connections. Without # this, the editor flashes a "Site can't be reached" error # while `npm install` is running. - if self.frontend_port and self._frontend_ready: + # Also gated on `running`: a vite that crashed or got orphaned still + # has _frontend_ready=True, and handing the webview that dead port is + # the ERR_FAILED you see on reopen. No live process, no URL. + if self.frontend_port and self._frontend_ready and self.running: return f"http://127.0.0.1:{self.frontend_port}/" return None @@ -477,6 +480,10 @@ class AppRuntime: if not self.process: return rc = await self.process.wait() + # Unclean death (vite crash, OOM, orphaned parent) must drop readiness; + # otherwise frontend_url keeps advertising a dead port and the preview + # navigates into ERR_FAILED. stop() already does this for clean stops. + self._frontend_ready = False self._broadcast(LogLine("runtime", f"[runtime] backend exited with code {rc}"))