From f1bc0657305eff8bd404e75c10ba57adb082436f Mon Sep 17 00:00:00 2001 From: Nariman Jelveh Date: Thu, 30 Jul 2026 18:11:12 -0700 Subject: [PATCH] GUI: fix dev-server port-retry crash under Express 5 (#3482) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Express 5's app.listen wraps the listen callback in once() and also invokes it on 'error', with the error as the first argument — at which point server.address() is null, so the startup log threw a TypeError and killed the process before the EADDRINUSE handler could try the next port. Bail out of the callback when it receives an error and let the 'error' listener own the retry. Verified: with 4000 occupied the server now logs the retry and comes up on 4001; with the port free it binds 4000 as before. --- src/gui/dev-server.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/dev-server.js b/src/gui/dev-server.js index 82166d031..8c5791ec1 100644 --- a/src/gui/dev-server.js +++ b/src/gui/dev-server.js @@ -86,7 +86,11 @@ const startServer = (attempt, useAnyFreePort = false) => { useAnyFreePort = true; // Use any port that is free } - const server = app.listen(useAnyFreePort ? 0 : port, () => { + // Express 5 invokes the listen callback on 'error' as well, with the + // error as its first argument — in that case server.address() is null, + // so bail and let the 'error' listener below own the retry. + const server = app.listen(useAnyFreePort ? 0 : port, (err) => { + if ( err ) return; console.log('\n-----------------------------------------------------------\n'); console.log('Puter is now live at: ', chalk.underline.blue(`http://localhost:${server.address().port}`)); console.log('Backend (API) origin: ', chalk.underline.blue(apiOrigin));