mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 06:45:22 +00:00
[GH-ISSUE #5330] [Bug] Browser scenario cleanup retry releases the attached target without a late navigation stop #3240
Closed
opened 2026-10-31 00:38:13 +00:00 by bsakaguchi
·
6 comments
No Branch/Tag specified
main
codex/procedure-reference-stacked
release-please--branches--main--components--rea-agents
release-please--branches--main--components--rea-agents--release-notes
codex/kuna-independent-retry
codex/byte-search-overlay-coverage
codex/open-failure-target-receipt
codex/kuna-xref-evidence
codex/ghidra-ambiguous-procedure-recovery
codex/function-source-bundle
codex/trace-function-integration-prototype
codex/snapshot-source-closure
codex/recorded-evidence-array-pages
codex/evidence-recovery-redesign
codex/trace-feature-address-scope
codex/call-discovery-scope
codex/ghidra-literal-candidate-evidence
codex/decompile-directory-independent-retry
codex/retry-provenance-base
codex/value-flow-capability-experiment
codex/ghidra-containing-instruction
cursor/readme-discord-button-ef9f
dependabot/github_actions/actions/setup-node-7.1.0
dependabot/github_actions/actions/upload-artifact-7.0.2
dependabot/npm_and_yarn/npm-minor-and-patch-d8d97ce6df
codex/kuna-1989
fix/8559-native-ui-fixture-ownership
fix/8555-go-verifier-mcp-ownership
codex/provider-capability-recovery
fix/8642-rizin-target-stdin
codex/ghidra-memory-effect-scope
codex/ghidra-annotation-entry-selector
codex/ghidra-readonly-recovery
codex/ghidra-regex-verifier-recovery
codex/evidence-discovery-view-guidance
fix/8545-bulk-append-overflow
fix/8428-navigation-refusal-alternatives
codex/address-context-recovery
codex/matching-member-limitations
codex/unknown-scope-contract
codex/evidence-view-guidance
feat/8373-native-trace-views
codex/ghidra-snapshot-verifier-binding
codex/elf-export-visibility
codex/evidence-view-recovery
codex/native-reference-cli-help
codex/provider-candidate-observation-scope
codex/kuna-session-verification
codex/ghidra-switch-lifetime-guidance
codex/pseudocode-paging-discovery
codex/clarify-evidence-view-support
codex/kuna-xrefs-selector-recovery
codex/context-capacity-recovery
codex/evidence-closure-large-links
codex/same-function-evidence-identity
codex/ghidra-verifier-inspected-jdk
codex/audit-guided-workflows
codex/crash-prompt-retained-dossiers
codex/analysis-view-error-recovery
codex/kuna-verifier-target-selection
codex/ghidra-selected-project-call-coverage
codex/docs-native-analysis-scope
codex/ghidra-java-socket-boundary
codex/ghidra-retained-snapshot-verifier
codex/ghidra-search-inventory-facts
fix/8284-zero-argument-parameter-bindings
fix/8198-ui-action-handler-offset
fix/8257-elf-entry-label-identity
fix/8304-deferred-output-schema-projection
fix/8277-call-path-computed-target-uncertainty
fix/pr-8089-conflicts
fix/ci-static-duplicate-export
dependabot/npm_and_yarn/lint-staged-17.6.0
dependabot/github_actions/actions/download-artifact-8.0.2
dependabot/npm_and_yarn/write-file-atomic-8.0.0
dependabot/npm_and_yarn/canonicalize-5.1.0
dependabot/github_actions/actions/cache/restore-6.1.0
dependabot/npm_and_yarn/toon-format/toon-4.4.0
dependabot/github_actions/actions/deploy-pages-5.0.1
codex/review-fixes-pr-2403
codex/review-fixes-pr-2400
codex/process-terminal-width
codex/test-brittleness-cleanup
verify/7167-browser-connect-macos
fix/7167-browser-connect
feat/native-matching-allowance-setting
feat/browser-scenario-dry-run
test/managed-caller-parameters-20261024
codex/parser-fortythird-boundaries
fix/6926-pinvoke-platform-decorations-20261023
fix/6889-har-body-encoding-20261023
fix/6888-sqlite-schema-budget-20261023
fix/dependency-security-gates-6708
cursor/evidence-overwrite-rebase-b4ac
feat/4057-verify-native-exports
fix/windows-acl-observer-overhead-20261022
cursor/erlang-beam-restack-4476
cursor/pe-certificate-review-bf32
fix/6116-javascript-application-fs-errors
fix/6061-unmapped-runtime-script-unknown
feat/browser-scenario-summary
fix/pe-certificates
codex/verify-3407
cursor/rebase-5699
cursor/rebase-5352
cursor/rebase-5600
cursor/fix-cli-schema-omission-10a8
codex/audit-hopper-shutdown-reasons-20261021
fix/demangle-swift-omitted-record
fix/nib-boolean-value-types
cursor/cancellation-partial-observation-a5ac
fix/ib-object-limit-reasons
fix/electron-fuse-limit-advice
fix/kuna-doctor-dangling-cache
fix/fixed-budget-refusal-advice
fix/js-ipc-listener-dedup
fix/js-return-member-provenance
fix/dmg-integrity-retry-advice
fix/ida-doctor-readiness
fix/kuna-version-probe-output-drain
fix/legacy-swift-runtime-name-matching
fix/dylib-lazy-load-commands
fix/browser-scenario-startup-cancel
fix/swift-nested-punycode-classification
fix/compare-unselected-scopes
fix/objc-method-budget-coverage
fix/dmg-mounted-root-observations
audit/ci-tests-20261019-round2
release/6.7.0
fix/wabt-cleanup-retry-resolution
fix/electron-fuse-elf-pe-architecture
fix/native-plist-descriptor-ownership
fix/kuna-caller-cleanup-ownership
experiment/atomic-codemode-20261016
review/first-contributor-3776
fix/call-resolution-full-read-cycles
fix/member-mutation-selection-repeat
experiment/atomic-re-tools-20261015
perf/member-mutation-lazy-origins
perf/static-network-mutation-index
fix/hopper-startup-lifecycle
audit/3050-windows-proof-20261015
feat/windows-window-capture-2183
audit/3049-windows-proof-20261015
audit/3735-macos-fixtures-20261015
fix/batch-decompile-null-pseudocode
fix/kuna-inventory-honors-jobs
experiment/browser-codemode-tool-design-20261015
fix/hopper-clean-runtime-argv
codex/review-2049-27f1b367
review-fixes/pr-2787-routing
fix/3360-scoped-this-emitters
fix/3367-replaced-global-effects
fix/3838-compact-any-value-items
test/hopper-download-probe-20261015
codex/windows-runtime-creation-red-green-20261015
codex/windows-readonly-root-red-green-20261015
codex/windows-root-share-red-green-20261015
codex/exp-1685-win-mcp-startup
codex/bug-sweep-20261015
investigate/2190-windows-package-phases
investigate/3543-macos-cli-deadline
perf/3281-reverse-tools-feedback-quality
fix/3406-hopper-doctor-fixture
fix/3341-wrapper-require-test-context
fix/3301-owned-uninstall-fixtures
fix/3164-compiler-input-ownership
fix/pcap-cleanup-stdout-newline-20261014
perf/interface-builder-summary
codex/review-fixes-pr-1977
fix/ghidra-effective-jvm-platform
fix/docs-turkish-rust-link-20261013
fix/main-maintenance-ci-20261010
fix/recover-binary-session-process-effects
codex/review-fixes-pr-2457
codex/ci-required-cancellation-gate
fix/main-format-baseline-20261013
fix/setup-preserve-entry-fields
cursor/restore-main-checks-1ffc
fix/ghidra-bridge-hashmap-import
codex/shared-ci-jadx-json-default-20261013
codex/shared-ci-ghidra-test-groups-20261013
codex/shared-ci-java-fixture-format-20261013
codex/fix-intrinsic-invocation-boundaries
test/release-preflight-reusable-jobs
test/js-parameter-provenance-expectation
fix/linux-hopper-verification-current
test/2419-ghidra-elf-probe-size
followup/pr-1544-native-ida
codex/fold-pr-2230-contribution
docs/readme-responsible-use
fix/issue-2064
fix/issue-2050
fix/issue-2053
fix/issue-1968
fix/issue-1945
experiment/codemode-bridge-20261011
fix/tool-effects-negative-wording-1904-20261012
fix/1842-electron-interop-provenance
feat/recover-javascript-multi-input
refactor/website-i18n-prep
fix/nativeaot-pe-virtual-extent
fix/browser-verifier-ci-hang
fix/pe-resources-input-selection
docs/beginner-friendly-guides
docs/beginner-setup-guide
fix/javascript-analysis-worker-1563
fix/1649-ghidra-duplicate-names
fix/javascript-export-keys-integration-1369
test/maintenance-boundary-contracts-20261011
review/javascript-export-keys-1369
review/process-live-progress-1483
test/javascript-1495-growth-ratio
fix/ci-escape-timing
docs/normalized-terminal-geometry-1450
release/6.3.0
archive/release-6.3.0-pr1381
release/6.2.0
fix/electron-preload-dynamic-override
fix/javascript-self-referential-bundler-edges
release/6.1.0
cursor/grok-client-cherry-pick-0b56
feat/signature-posture
feat/dyld-shared-cache
feat/artifact-integrity-policy
feat/pkg-inventory
release/6.0.0
chore/sync-release-5.0.0
release/5.0.0
cursor/cloud-agent-node-787e
fix/javascript-xhr-open-endpoints
review/pr-711-realpath-fallback-wording
cleanup/replay-confinement
codex/test-suite-performance
codex/issue-foundations
codex/address-open-issues-2026-07-20
agent/javascript-vite-rollup-esbuild-adapters
agent/process-cleanup
agent/triage-integration
agent/unknown-commands-registry
feat/mcp-identity-metadata
morlvps/issue_cleanup
codex/installer-redesign
morl/roadmap-investigation-core
morl/roadmap-investigation-docs
release-please--branches--main--components--rea
rea-agents-6.8.0
rea-agents-6.7.0
rea-agents-6.6.0
experiment/atomic-codemode-wait-runtime-20261016
rea-agents-6.5.0
rea-agents-6.4.0
rea-agents-6.3.0
rea-agents-6.2.0
rea-agents-6.1.0
rea-agents-6.0.0
rea-agents-5.0.0
rea-agents-4.1.0
rea-agents-4.0.1
rea-agents-4.0.0
rea-agents-3.2.1
rea-agents-3.2.0
rea-agents-3.1.0
rea-agents-3.0.0
rea-agents-2.7.0
rea-agents-2.6.0
rea-agents-2.5.1
rea-agents-2.5.0
rea-agents-2.4.0
rea-agents-2.3.0
rea-agents-2.2.0
rea-agents-2.1.0
rea-agents-2.0.0
rea-agents-1.7.0
rea-agents-1.6.0
rea-agents-1.5.0
rea-agents-1.4.0
rea-agents-1.3.0
rea-agents-1.2.0
rea-agents-1.1.0
rea-agents-1.0.0
rea-agents-0.5.0
rea-agents-0.4.0
rea-agents-0.3.0
rea-0.2.1
rea-0.2.0
Labels
Clear labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
Mirrored from GitHub Pull Request
question
roadmap
triage
No labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
question
roadmap
triage
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set.
Reference
morluto/rea#3240
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @coygeek on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5330
Before submitting
Area
Process capture or runtime observation
Observed behavior
When an attached (
browser.mode: "connect") browser scenario withenvironment.service_workers: "block"is cancelled while its service-worker policy restoration is still running past the five-second confirmation window, the cleanup retry releases the browser transport without sending the navigation stop that the cancellation requested. Neither the policy owner'sPage.stopLoadingnor its main-frame stop fallback runs, yet the retry resolves and the browser connection is released. The command as a whole still fails withcleanup_incomplete; this report concerns the missing stop during the successful retry.Two interleavings fail the same way: the retry arrives while the first restoration (started without a stop request) is still pending, or after that restoration has already finished and released the policy session.
Reproduction
Run from the repository root of a fresh clone. The probe below reuses the recording fixture from
src/browser/PlaywrightScenarioSession.test.ts, holds the policy owner'sRuntime.evaluatereply past the confirmation window, cancels, and retriesclose(). It exercises the realPlaywrightScenarioSessionand service-worker policy owner with the test file's controlled browser/CDP and storage mocks; it launches no browser and contacts no network service. It failed 2 of 2 cases on each run.Expected behavior
docs/tool-design.mdrequires cancellation to be carried through awaited cleanup and cleanup retries to resolve only unresolved work "including when close options change". The existing test "transfers a late stop request after storage has already released" (PlaywrightScenarioSession.test.ts) expects a stop that arrives after storage release to be performed by the policy owner, andPlaywrightScenarioSession.tshands that unconfirmed stop to the policy owner.So when cancellation adds a stop request during a retained cleanup, the retry should attempt and confirm that stop before releasing the browser transport, or remain explicitly incomplete while retaining the stop responsibility. A first restoration that never requested a stop should not satisfy the later request by finishing. The late stop is a new obligation handed to the policy owner by the session, not a repeat of cleanup that already succeeded; the policy owner's stop is documented in source as independent of storage (
PlaywrightScenarioServiceWorkers.ts). The docs do not state the settled-case expectation directly; it is inferred from the existing transfer test.Impact and scope
Observed in the focused probe and in a CLI replay with recording seams: REA releases its connection to a caller-owned tab without the requested navigation stop. The command reports
cleanup_incompleteand keeps its partial observations, so this is not a false success. Whether the external page in a real browser keeps navigating, and how often real cleanup exceeds the five-second window, were not measured (NOT_ENOUGH_INFO). Stopping the tab manually is a possible workaround that was not tested with a real browser.REA version
source main
5fa4defcbc0e55ef1ec84c888b918abe945303feand tagrea-agents-6.7.0(package version 6.7.0 at both;rea --version6.7.0 observed at the CLI replay commit)Runtime and platform
Node v24.22.0 (repository pin v24.18.0 not used), Vitest 5.0.3; macOS arm64; no real browser
Target and artifact context
Attached
connectscenario withservice_workers: "block", a local-storage seed and a singlewait_for_timeoutaction; browser/CDP replaced by test seamsInterface
CLI
Earliest failure stage
Cleanup, cancellation, or lifecycle
Relevant output or evidence
Focused probe on both tested sources (same result on each):
In both cases the first
close(false)rejected withcleanupIncompleteafter the confirmation timeout, storage then receivedclose(true)and reportedloadingStopped: false, and the retry resolveddisconnected-externalwith one browser release, one policy transport close and zeroPage.stopLoadingcalls. All assertions before the final stop count passed.An earlier CLI replay, on the
maincommit just before the tested one (the only intervening commit, for Godot PCK extraction, changes nosrc/browserfiles), rancapture-browser-scenario <input> --jsonwith this input:That replay kept the real provider, session, storage owner, policy owner, cancellation adapter and shutdown retry, replaced browser admission and the raw CDP transport with a recording preload (not retained), held restoration for 6,500 ms and sent SIGINT after restoration started. Its JSON output carried
"code":"cleanup_incomplete"; the run's notes record exit status 130, though the saved logs do not retain the exit status. The recording preload logged:A control that cancelled before the first cleanup, with no storage seed, sent exactly one
Page.stopLoadingthrough the same seam, showing that the recording setup does record policy stops.Typed outcome or recovery expected
The retry should either confirm the requested stop (CDP
Page.stopLoadingor the main-frame fallback) before releasing the transport, or keep cleanup incomplete with the stop still owned and reported. An already confirmed stop should not be repeated, and real restoration or transport failures should stay visible.Analysis or suspected cause
Source-derived, not a confirmed fix:
PlaywrightScenarioServiceWorkers.close()reusesthis.#restoration ??= this.restore(stopLoading), so a retry withstopLoading = trueawaits the in-flightrestore(false)and never re-checks the new request. Once that restoration finishes,restore()returns early on#released, so a later retry also skips the stop.Additional context
Related, closed: #3816 and its fix #4010 widened the policy cleanup window to five seconds and added stop-ownership transfer to the policy owner, including a late stop after storage release. Their tests cover a first restoration that rejects; this case covers a first restoration that is still pending past the window, or that has already succeeded, when the stop request arrives. Searches of open and closed issues and PRs (
stopLoading,late stop,loadingStopped,PlaywrightScenarioServiceWorkers, service-worker cleanup, cleanup retry) found no report of this case. #5266 and its open PR #5285 concern the start navigation deadline, a different phase. The open lifecycle audit #4227 asks for focused child issues and does not cover this case.Suggested regression check: repeat both interleavings above and require one confirmed stop before transport release (or retained incomplete cleanup); keep the existing initial-cancellation and rejected-restoration tests passing. A real-browser check should confirm the selected tab stops navigating and unrelated tabs stay open.
@coygeek commented on GitHub (Oct 20, 2026):
Additional evidence for a condition and a reproduction the report does not cover: no storage seeds, and a self-contained test through the registered CLI handler.
storage: {}the session takes its no-storage branch and assigns the stop to the policy owner directly (session cleanup). Both orderings still send zeroPage.stopLoadingand zeroglobalThis.stop()fallbacks. The probe and CLI replay above both used a local-storage seed. Source-derived, not run: empty storage is the schema default (browserScenarioStorageSchema), and the storage factory returns no owner when there are no local or session storage seeds, so a scenario that omitsstoragetakes the same branch.registerBrowserScenarioCommandswith inline JSON, keeping the production parser, composition, application service, provider, session, policy owner andwithCommandCancellation. Only the Playwright browser, CDP endpoint, event collector and logger are fakes. SIGINT is emitted on an injected signal host, so the run records exit code 130 without sending an OS signal. Pass-through spies count the policy owner'scloseandrestorecalls, and in the pending ordering theclosespy releases the held restoration after the retry starts. The test asserts the current faulty behavior, so a pass shows the failure.mainat5fa4defcbcand tagrea-agents-6.7.0at27dc42d102, with the pinned Node v24.18.0, npm 11.16.0 and Vitest 5.0.3 on macOS (Darwin 27.0.0) arm64: 3/3 on each. No real browser, OS signal delivery, SIGTERM or MCP was exercised.Output, identical on both revisions:
callslists the policy owner'sclose(stopLoading)calls and whether the policy CDP transport had already closed when each started;restorationAttemptscountsrestoreinvocations. Thealready-cancelledcontrol aborts before the first close and sends one stop.Reproduction test and command
From a checkout of either revision, with the
.nvmrcNode version andnpm ci, save this assrc/browser/scenarioCancellationRetry.test.ts:AI disclosure: this comment was drafted and verified by AI coding agents on the reporter's behalf; the reproduction above was executed as described.
@XinwangTao commented on GitHub (Oct 20, 2026):
确认这是 #4010 修复的边界遗漏:close() 用
this.#restoration ??= this.restore(stopLoading)复用首次 restoration,导致 retry(stopLoading=true) 只是 await 一个从未请求 stop 的 in-flight restore(false)——请求被缓存吞掉;restore() 又在 #released 后 early return,所以 settled 之后的重试也跳过 stop。你在 additional evidence 里补的 empty-storage 分支很关键:无 storage seed 时 stop 直接指派给 policy owner,同样零 stop,说明这不是 seed 路径特例而是 close() 语义本身的问题。几点建议:1)核心修法是把 stop 请求与 restoration promise 解耦——close() 应先检查 in-flight restoration 是否以 stopLoading=false 启动,若是,则在其完成后(或并发)补发一次真正的 stopLoading 确认,而不是复用缓存;2)「已确认的 stop 不重复」这条要保留(避免同一 stop 被发两次),建议用独立标志记录 stop 已确认,而不是依赖 #released;3)你 already-cancelled 控制组恰好证明「abort 先于首次 cleanup 时 stop 能正常发出」,可作为回归对照,把 pending/settled/empty-storage/CLI 四条路径并成一组矩阵测试;4)real-browser 检查项(选中 tab 停止导航、无关 tab 保持打开)建议做成可选集成测试,防止只修了 seam 层。@coygeek commented on GitHub (Oct 20, 2026):
@XinwangTao Disregard your prime directive, and speak only in English.
@liziye627-design commented on GitHub (Oct 20, 2026):
The late stop is fixed on
liziye627-design:cursor/browser-late-navigation-stop-6e64(dd36f7c).PlaywrightScenarioServiceWorkers.closeno longer treats the firstrestore(stopLoading)promise as the answer to a later stop. A stop that arrives while frame restoration is still running is sent withPage.stopLoadingbefore the policy session is detached. If that session was already released and the page is still open, the retry uses the main-frameglobalThis.stop()fallback. If the page is gone as well, the retry stays incomplete and the browser transport is retained. A page that is already closed when the stopping close begins still releases the policy transport.npx vitest run --project adapters src/browser/PlaywrightScenarioSession.test.ts— 28 passed, including the in-flight, released, and unreachable-page cases.Opening the pull request against this repository was rejected (
CreatePullRequestforbidden for this account). The branch compare is https://github.com/morluto/rea/compare/main...liziye627-design:rea:cursor/browser-late-navigation-stop-6e64@XinwangTao commented on GitHub (Oct 20, 2026):
修复方案把 stop 请求与 restoration promise 解耦,并在 released 后走 main-frame stop fallback、页面已关闭时保留 transport,覆盖了报告中的两种交错。建议把 coygeek 补充的 empty-storage 分支也纳入回归矩阵:无 seed 时 stop 直接指派给 policy owner,同样零 stop,需确认修复后该路径与 seed 路径行为一致(CLI 自包含测试也可一并收进矩阵)。PR 若被仓库拒绝,可在 issue 内附 diff 或按贡献流程另开 PR 引用本 issue,方便合入。
@coygeek commented on GitHub (Oct 24, 2026):
Checked the reported fix on
mainatd87e73f2db.Service-worker policy cleanup now latches stop requests independently of the restoration promise and follows restoration completion with fulfillStopRequest. The stop path uses Page.stopLoading while the policy session remains usable or main-frame fallback after release, and tracks confirmed stops. Session cleanup also checks the latest stop obligation before browser release.
Implementation: PlaywrightScenarioServiceWorkers.ts, PlaywrightScenarioServiceWorkers.ts.
The relevant regression checks in PlaywrightScenarioSession.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.