Repository navigation
fix(browser): the CDP relay passes each answer on in order with the events around it - #628
Merged
Merged
Conversation
…vents around it The pipe's reader handed events to the relay as it read them, but an answer only reached its client once the command's task resumed, so an event the browser sent after an answer, read in the same chunk, could reach the client first. Playwright, given Runtime.executionContextCreated before Page.getFrameTree's answer, drops the context, and page.evaluate then waits for ever. A request's answered hook now hears its answer as the pipe reads it, and the relay sends its reply from there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale
added a commit
that referenced
this pull request
Nov 12, 2026
…628) Co-Authored-By: Claude Opus 5.5 <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
The browser's CDP relay could deliver an event before the answer that the browser sent ahead of it. When that happened to
Page.getFrameTree's answer, Playwright dropped the page'sRuntime.executionContextCreated, andpage.evaluatethen waited for ever. The relay now passes on each answer and each event in the order the browser sent them.It was found while testing #615. There, Playwright MCP's
browser_evaluatehung now and then in a new session. It can affect any CDP client through the relay, Browser Use included.Why it happened
The relay's pipe reader read one message at a time and handled each according to its kind:
When the browser's answer and the events after it arrived in one read, the reader handed the events on before the command's task ran. So the client got them first.
The browser sends
Page.getFrameTree's answer before the execution contexts thatRuntime.enablereports. Playwright, getting a context for a frame it doesn't know yet, ignores it, and so it never learns the page's main world.This goes back to the relay's start (#482). #613 wrapped each request in a task of its own, which added a hop before the reply and widened the window.
What changes
DevToolsPipe.requesttakes anansweredhook. The reader calls it with the answer as it reads it, in order with the events before and after it, then resolves the request as before.requestwith the hook, so other callers are unchanged.Test plan
Unit:
test_devtools_pipe.py: the real pipe over OS pipes, with an answer and an event written in one write. The hook hears the answer before the listener hears the event.test_browser_cdp.py: an answer reaches its client before the event the browser sent right after it.A stress loop on a browser computer, local Docker (Mac, arm64), on feat(drivers): the browser computer serves Playwright MCP's browser_* tools, attached over CDP (FD-4955) #615's branch, whose Playwright MCP opens a CDP connection per session. Each round calls
browser_evaluatein a new session.In each hang the browser's log showed every command answered, and the evaluate never sent.
Docs
None: the relay's contract is unchanged. It now keeps the browser's order, as a client already assumed.
🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; no actionable issues were found.Summary
The relay now queues browser replies from the pipe reader, preserving their order with nearby events.
Diagram
sequenceDiagram participant Browser participant Pipe as DevToolsPipe participant Relay participant Client Browser->>Pipe: Command answer Pipe->>Relay: answered callback Relay->>Relay: Queue client reply Pipe->>Pipe: Resolve waiting request Browser->>Pipe: Following event Pipe->>Relay: Event listener Relay->>Relay: Queue event Relay->>Client: Reply, then eventReviews (1) · Last reviewed commit: "fix(browser): the CDP relay passes each ..." · Reviewed by Greptile