ui-react: attribute unexpected browser closure during parallel-session reload
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- playwright, typescript
- Domain
- testing-qa
Research direction
Read packages/ui-react/tests/parallel-sessions-runtime.test.ts around the launch, teardown, device setup and failing reload at line 816. Re-run the recorded check:pr command from the isolated checkout with DEBUG=pw:browser, capturing owned-process PID, exit or signal, disconnect and cleanup chronology. Done means evidence identifies the browser loss or clearly records the remaining gap and next capture action, while preserving all 46 cases and assertions.
Written by the indexing model from the issue text.
Description
Out of scope
Do not weaken recovery, approval, draft, tracking or staged-file assertions; raise deadlines; skip runtimes; change default browser/worker concurrency; retry a failure into a green claim; or select a production correction without evidence. This is separate from #2202's pre-send readiness timeout, #2280's steering-Undo timeout and the delivered #1993 response-binding repair.
Context
While qualifying #2288 for #2202, the normal guarded local preflight at head 02b320432bbced92add9964b237ef3cdd5275d05, base dcc09e9c8601f6513eec907cfbf7d3ffbc01bf16, encountered a closed-target error during a 1440px reload, followed by shared-browser-closed failures. The first failure is not a timeout:
mounted parallel sessions > 1440 desktop, light, fine pointer, reduced motion: an approval, all four question forms and running work fold into a summary; a reconnect, a reload and a host restart keep them, and none reads done
The body reaches await a.page.reload() at (await a.page.reload, packages/ui-react/tests/parallel-sessions-runtime.test.ts:816) after aborting recovery-route reads, then throws reload: Target page, context or browser has been closed. Playwright records navigation to the fixture origin while waiting for load. Body time: 15,787.90 ms. The next 17 cases fail immediately at browser.newContext, so this is one initiating closed-target failure followed by cascades, not 18 independently established defects. The first API error alone does not establish when or why the shared browser became unavailable.
The file reports 28 pass / 18 fail, 1,169 assertions, 46 cases, 412.06 s. Required preflight exits 1. Strict types and preceding lint/metadata/fast checks pass. The historical #2202 1279px Subagent Deny case passes before the browser loss. No retry of this failed preflight has been performed.
At this exact source, the browser launches at (browser = await chromium.launch, packages/ui-react/tests/parallel-sessions-runtime.test.ts:241), explicit file teardown closes it at (await browser?.close, same file:247), and device creation owns each context at (async function device, same file:357-428). The initiating failure has no retained browser PID, child exit code/signal, pw:browser lifecycle log or close-call ownership trace.
Conditions and observed limits
Bun 1.4.3, Playwright 1.63.0, real Chromium 152.0.7977.82, frozen dependencies, mandatory package/client build, BRAIN_REQUIRE_CHROME=1, the original test preload and local-origin browser guard. This is the ordinary serial check:pr import-feedback phase, not a hosted N=2 comparison. Another diagnostic Bun run was active in a separate dedicated checkout and capability-cleared network namespace; shared-host load is uncontrolled and is not a selected cause.
No Chromium coredump was recorded in the 10:20–10:25 UTC window on 2026-10-17. Kernel and systemd-oomd logs in that window supply no OOM-kill, segfault or process-termination attribution. A later memory snapshot is not proof of memory conditions at exit. These negative observations do not rule out every crash, signal or resource limit.
Earlier logger versions passed complete 46-case native matrices at their own source/base identities; the concurrent frozen historical run also passes its matrix. Neither is a matched-source causal control for this occurrence. The latest logger adds passive profile/admission snapshots, but no action, wait or assertion changes; whether source, runtime or an external termination is responsible remains unestablished.
Scope
Capture the browser/process lifecycle at the initiating reload and establish why the browser is gone before choosing a correction. Found during #2202; supports #736's deterministic host-isolated verification outcome and #2121's qualification obligation. #736 already has 100 direct native children at this readback, so this remains standalone by reference; no existing child was moved.
Acceptance criteria
- Preserve the first failure, all 17 cascades, exact source/runtime/command and limits; do not conflate it with the historical unavailable-Send failure.
- Capture launch PID, exit code/signal, disconnect and explicit close/cleanup chronology with owned-process evidence. A
DEBUG=pw:browserobservation-only arm is an appropriate starting point. - If it recurs, distinguish intentional cleanup, protocol disconnect, native termination and resource enforcement using direct evidence. Record non-reproducing controls without calling them fixes.
- Establish a source-bound correction or document the remaining evidence gap and exact next capture action. Any ownership correction must prove an unrelated process/control survives cleanup.
- Preserve all 46 matrix cases, original deadlines, native input, offline guards and behavioral/negative assertions. Any correction gets an intended failing-first or mutation/restoration receipt, current local preflight and complete selected hosted proof.
Verification
From an isolated checkout at the recorded source with its own frozen dependencies:
BRAIN_REQUIRE_CHROME=1 PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium bun run check:pr --base origin/main
The original import-feedback merge base is dcc09e9c8601f6513eec907cfbf7d3ffbc01bf16. The affected feedback selects packages/ui-react/tests/parallel-sessions-runtime.test.ts. For the next diagnostic arm, retain the same source/actions and add DEBUG=pw:browser to capture process lifecycle. Keep source and actual tested base/head identities separate if main advances. Do not widen waits or suppress browser-close failures.
Contract impact
None selected. This is an internal native-test/process-lifetime investigation, not an established product or protocol regression. Needs reproduction with exit/ownership evidence before an implementation is agent-ready.
Triage 2026-10-17: p2 reflects wanted unscheduled diagnosis, without inheriting the candidate's urgency. Retain needs: repro: the initiating browser exit/close-owner evidence is missing and the 17 later closed-context failures are cascades, not independent causes. Preserve the existing original-source capture recipe and all failed identities. Standalone supporting work for #736, whose native child list is full; discovery during #2202 does not make this browser-lifecycle diagnosis part of its composer deliverable.
Current diagnostic distinction — triage 2026-10-21
The later controlled page-only closure reproduces the first reload error while the same browser still opens an independent context and evaluates a sentinel. It does not reproduce the subsequent 17 newContext failures. Therefore preserve the distinction between the initiating closed-target API error and independently established browser-wide termination; neither actor nor exact close/exit chronology is known for the original run.
The native lifecycle, GPU/shared-memory, crash-observation, raster-concurrency and NetLog controls in the comments did not capture the original browser-wide failure. Their passing 104-assertion scenario results remain separately attributed. The earlier six-session cancellation in a crash-observation arm occurred before reload and is tracked in #2395/#2394; valid-capacity controls reach reload successfully but do not diagnose the historical browser loss. #2471’s later post-Send initial-card timeout also does not establish a common initiating mechanism.
The required next evidence remains a naturally failing original-boundary trace joining actual browser PID/start/exit, page/context state and explicit close/cleanup ownership before the cascades. Preserve the original failure/order and all guards; no source correction, new browser execution, causal fix, priority, parent or readiness change is made. Keep needs: repro and the existing #2202 qualification relationship.
- Dominant language
- TypeScript
- Stars
- 3
- Forks
- 0
- Avg merge
- 5h 8m
- Merged PRs (30d)
- 946
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from schlessera/brain-kit
-
agent-ready area: backends area: ui-sdk priority: p1 type: fix
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
schlessera/brain-kit#3519 · 1 comment ·
Maintainers usually reply within 1 day
-
agent-ready area: docs priority: p3 type: docs
Difficulty 1/5 Under an hour Newbie friendliness 78/100
schlessera/brain-kit#3479 ·
Maintainers usually reply within 1 day
-
agent-ready area: ci priority: p2 type: fix
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
schlessera/brain-kit#3318 ·
Maintainers usually reply within 1 day
-
agent-ready area: ui-server priority: p2 type: fix
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
schlessera/brain-kit#3259 ·
Maintainers usually reply within 1 day
-
agent-ready area: ui-kit priority: p2 type: docs
Difficulty 1/5 Under an hour Newbie friendliness 90/100
schlessera/brain-kit#3188 ·
Maintainers usually reply within 1 day
All issues in schlessera/brain-kit
Similar issues
-
cloudflare-cache-binding: `unstorage://` keys are rejected by the Cache API, cache never storesOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Maintainers usually reply within 2 days
-
reproduced
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
anomalyco/opencode#62052 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
strapi/design-system#2084 ·
Maintainers usually reply within 3 days
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
Maintainers usually reply within 1 day