fix(browse): resolve Windows EADDRINUSE race condition + /health data leak#638
Open
raf-andrew wants to merge 1 commit intogarrytan:mainfrom
Open
fix(browse): resolve Windows EADDRINUSE race condition + /health data leak#638raf-andrew wants to merge 1 commit intogarrytan:mainfrom
raf-andrew wants to merge 1 commit intogarrytan:mainfrom
Conversation
On Windows via the Node.js polyfill, Bun.serve() wraps http.createServer() which is async — server.stop() doesn't wait for the port to actually be released before returning. This causes EADDRINUSE on every cold start when findPort() races with itself. Fix: use net.createServer() in a Promise wrapper that resolves only after server.close() fires its callback, guaranteeing the port is fully free. Also removes currentUrl from the unauthenticated /health endpoint to avoid leaking active page context to any local process that can reach the server. Fixes: garrytan#486 (Windows EADDRINUSE race), garrytan#473 (health endpoint data leak) Supersedes: garrytan#490, garrytan#493 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
findPort()race condition causing 100% cold-start failurecurrentUrlfrom unauthenticated/healthendpointRoot cause (#486)
findPort()inbrowse/src/server.tscalledBun.serve()thentestServer.stop()to test if a port was free. On Windows, where Bun can't launch Chromium and the Node.js polyfill is used,Bun.serve()wrapshttp.createServer().listen()which is asynchronous.stop()callsserver.close()without awaiting its callback — sofindPort()returned a port that the test server was still holding, causingEADDRINUSEevery time the real server tried to bind.Fix: Replace
Bun.serve()port testing withnet.createServer()in a properPromisewrapper that resolves only after theserver.close()callback fires.netis available in both Bun native and Node.js, so this works on all platforms.Security fix (#473)
Removed
currentUrlfrom the/healthresponse. The health endpoint requires no auth token (by design — it's needed by the CLI before the token is read). Any local process that can reach the server could poll this endpoint to observe what page the user is browsing. The field is not used by any gstack skill.Test plan
$B goto https://example.com5× on Windows — noEADDRINUSEerrors$B statusreturnshealthywithoutcurrentUrlin the JSONnet.createServerresolves correctly under both Bun native andnode server-node.mjsSupersedes: #490, #493
🤖 Generated with Claude Code