fix(runtime): disable Playwright process signal handlers - #19
Draft
cursor[bot] wants to merge 1 commit into
Draft
Conversation
Playwright defaults handleSIGINT/TERM to true, so after createSession it registers handlers that close Chromium and process.exit(130) on SIGINT, racing companion/MCP graceful shutdown. Own lifecycle like Playwright's embedded MCP launcher. Co-authored-by: esadrianno <esadrianno@gmail.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.
Bug and impact
After the first
createSession, Playwright registers defaultSIGINT/SIGTERMhandlers (handleSIGINT/handleSIGTERMdefaulttrue). On Ctrl+C / SIGINT those handlers close Chromium and then callprocess.exit(130), racing companion/MCPcloseGracefully(runtime.shutdown→app.close→exit(0)). The HTTP server may not drain; exit is unclean; this compounds dead-browser / orphan races during daemon stop.Trigger: create at least one session (browser launched), then SIGINT the companion process.
Root cause
BrowserRuntime.launchBrowsercalledchromium.launch/webkit.launchwith onlyheadless, leaving Playwright process-signal ownership enabled. Playwright’s own embedded MCP launcher setshandleSIGINT: false/handleSIGTERM: falsefor the same reason.Fix
Pass
handleSIGINT: false,handleSIGTERM: false, andhandleSIGHUP: falseon both Chromium and WebKit launches so companion/MCP own lifecycle.Validation
pnpm --filter @webchain/runtime test— 27 passed (2 new launch-option assertions)pnpm --filter @webchain/runtime typecheck— greenDistinct from #10–#18
#12/#15 address companion/runtime shutdown ordering and
Promise.allSettled; neither disables Playwright’s process signal handlers (verified on those branches).