Skip to content

fix(ui-server): auto-fallback to a random port on EADDRINUSE (#82)#119

Merged
Mingwwww merged 2 commits into
OpenBMB:mainfrom
xiaohongrsx:rsx
Jun 3, 2026
Merged

fix(ui-server): auto-fallback to a random port on EADDRINUSE (#82)#119
Mingwwww merged 2 commits into
OpenBMB:mainfrom
xiaohongrsx:rsx

Conversation

@xiaohongrsx
Copy link
Copy Markdown
Contributor

Summary

Fixes #82 — the auto-install script aborts when ports 3000/3001 are already in use.

The online installer launches the Web UI via npm run start:built, which runs ui/server/index.js directly. That code path called server.listen() with no error handler, so a busy port crashed the process with an uncaught EADDRINUSE exception and aborted the installation instead of recovering.

Changes

ui/server/index.js:

  • Add listenWithPortFallback(): on EADDRINUSE, retry on a random high port (20000–59999), up to 5 attempts, then exit with a clear, actionable message.
  • Random ports are used instead of preferred + 1 because adjacent ports are frequently held by the same multi-port application that already took the preferred one.
  • The actually-bound port is now used for the "Server Ready" log line and the browser auto-open.
  • The bound port is written back to process.env.SERVER_PORT so modules that self-reference it (e.g. routes/taskmaster.js) hit the correct port after a fallback.
  • Removed the pre-bind "production mode" log line that printed the preferred (possibly wrong) port.

Behavior

  • Preferred port free → binds it as before (no behavior change).
  • Preferred port busy → logs a warning, retries on a random high port, prints the real URL.
  • 5 failed attempts → exits with guidance to set SERVER_PORT manually.

Testing

Verified the fallback logic in isolation:

  • Preferred port free → binds preferred port. ✅
  • Preferred port occupied → falls back to a random high port and binds successfully. ✅

Non-EADDRINUSE errors (bad host, permissions) still reject and are not silently retried.

xiaohongrsx and others added 2 commits June 3, 2026 03:00
)

The online installer launches the Web UI via `npm run start:built`, which
runs ui/server/index.js directly. That path called `server.listen()` with
no error handler, so a busy port (e.g. 3000/3001 already taken by other
Node apps) crashed the process with an uncaught exception and aborted the
install instead of recovering.

Add listenWithPortFallback(): on EADDRINUSE, retry on a random high port
(20000-59999) up to 5 times, then exit with a clear message. Random ports
are used instead of preferred+1 because adjacent ports are often held by
the same multi-port app. The actually-bound port is logged, used for the
browser auto-open, and written back to process.env.SERVER_PORT so modules
that self-reference it (e.g. routes/taskmaster.js) hit the right port.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Force *.sh (and docker-entrypoint.sh explicitly) to LF via .gitattributes.
On Windows checkouts with core.autocrlf=true, git rewrote the Docker
entrypoint to CRLF, which made the Linux container fail to start with
`/usr/bin/env: 'bash\r': No such file or directory` and loop on restart.
Pinning eol=lf prevents the regression on every clone/pull.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Mingwwww Mingwwww merged commit c272623 into OpenBMB:main Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

用在线自动安装脚本安装时,当 3000和3001 端口被其它应用占用时的自动处理

2 participants