fix(click): bound boundingBox() in mouse-sequence fallback to prevent 30s timeout 500s#5663
Merged
skyfallsin merged 1 commit intoJul 19, 2026
Conversation
… 30s handler timeout 500s When a normal click attempt fails because the element detached after a page change (SPA re-render between snapshot and click), the mouse-sequence fallback called locator.boundingBox() with no timeout. Playwright waited its default 30s for the element to resolve, blowing the entire HANDLER_TIMEOUT_MS budget and surfacing as: click failed: action timed out after 30000ms -> 500 internal error Worse, that generic 'timed out after' error is classified by isTimeoutError() as a navigation timeout, so handleRouteError() destroyed the whole user session (fresh proxy/context) over a stale ref. Fix: - boundingBox() is now bounded to min(3s, remaining handler budget), floored at 500ms. - On timeout it throws a 422 'Element not actionable' error whose message deliberately avoids the 'timed out after' phrase, so the session survives and the client gets an actionable hint (snapshot + retry) in ~3s instead of a 500 after 30s. Adds tests/unit/clickBoundingBoxTimeout.test.js covering the source contract (no bare boundingBox() calls), the budget math, and the error classification.
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.
Problem
When a
/tabs/:tabId/clickrequest hits the mouse-sequence fallback and the target element has detached (page changed between snapshot and click — common on SPAs like LinkedIn search results),locator.boundingBox()is called with no timeout. Playwright waits its default 30s for the element to resolve, which blows the entire handler budget:Two compounding issues:
action timed out after 30000msmessage is matched byisTimeoutError(), and sinceclickis inNAVIGATION_TIMEOUT_ACTIONS,handleRouteError()destroys the whole user session (fresh BrowserContext + proxy) — losing every other live tab — over what is really just a stale ref.Observed in production logs (v1.11.2) during a LinkedIn people-search batch: two such 500s in one run, each costing ~31s and killing the session of a concurrently-used tab.
Fix
In
dispatchMouseSequence:boundingBox()is now bounded tomin(3000ms, remaining handler budget), floored at 500ms.Element not actionableerror that (a) returns in ~3s instead of 30s, (b) deliberately avoids thetimed out afterphrase soisTimeoutError()doesn't nuke the session, and (c) tells the caller tosnapshot+ retry — which is exactly what the existing post-timeout refresh path recommends.Tests
New
tests/unit/clickBoundingBoxTimeout.test.js(7 tests):boundingBox()calls remain in server.js; the call site usesbboxTimeout; the error carriesstatusCode = 422node --check server.jspasses; full unit suite: 661 passed, with the only failures (security.test.js,cookies.test.js) failing identically on cleanmasterin my environment (real-browser spawn tests), i.e. pre-existing/environment-dependent.