Skip to content

Fix stalled tab cleanup and verify target removal - #50

Merged
mandatoryprogrammer merged 4 commits into
mainfrom
codex/fix-tab-cleanup-fallback
Oct 4, 2026
Merged

mandatoryprogrammer merged 4 commits into
mainfrom
codex/fix-tab-cleanup-fallback

Conversation

@mandatoryprogrammer

@mandatoryprogrammer mandatoryprogrammer commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Stalled CDP calls can permanently strand tracked tabs. Chrome can also acknowledge Target.closeTarget while a navigating target remains alive. Bound cleanup and attachment, and confirm that the target is gone before discarding its tracking record. Refs #39.

  • Track target IDs before tab attachment. Give discovery and WebSocket attachment a five-second deadline, cancel pending HTTP requests/handshakes, and clean up targets when attachment fails.

  • Use one six-second budget for each cleanup attempt, including concurrent transport teardown. Try the existing session, the HTTP endpoint, then a bounded fresh browser session. Confirm target disappearance rather than trusting a successful close acknowledgement or an HTTP 404.

  • Join concurrent closes instead of replacing CRI close listeners. Keep unresolved targets tracked and retry with exponential backoff capped at 30 seconds; the reaper respects this backoff.

  • Isolate cancellable CRI construction and forced transport shutdown in cdptransport.js. Its internal integration explicitly checks the existing 0.33.3 version, so an unreviewed upgrade fails visibly rather than silently losing cancellation. Internal notes document the recovery behavior and upgrade requirement.

  • Include the new transport adapter in the Docker image so the container can load cdp.js at startup.

Validation

CI passed on ee79ea6b53025d01fad1c9e8171358642c84be0c: docker-build (ubuntu-latest) and compose-e2e. Successful CI run.

Local validation used existing dependencies, Node 18.20.4, Chrome 152.0.7977.64, disposable headless profiles, and loopback HTTP/CDP fixtures. No dependencies were installed and no test files are included.

  • A withheld primary close command recovered through HTTP in 1.518 seconds, with zero pending CDP callbacks afterward.
  • A stalled tab transport was terminated within its deadline.
  • An unacknowledged attachment handshake was canceled, its target removed, and fixture sockets released in 5.148 seconds.
  • Proxy-generated 200 and 404 responses with a target still present both reached the fresh-session fallback and closed the real target.
  • An outage affecting both fallback paths, with stalled primary and tab transports, returned in 6.002 seconds; tracking survived and retry removed the target after connectivity returned.
  • Navigation, fetch, cookie, redirect, four-request concurrency, and 30-second timeout/recovery checks passed. The two aggregate tab-count assertions that previously failed now pass as well: only the original blank tab remains.
  • node --check cdp.js, node --check cdptransport.js, adapter import, and git diff --check passed.

Manual run commands used temporary verification scripts outside the repository:

node browser-fixed-check.mjs fixed
node edge-runtime-check.mjs fixed

Each script launches an isolated Chrome profile with --headless=new --remote-debugging-address=127.0.0.1 --remote-debugging-port=0 --disable-background-networking --disable-extensions --no-first-run --no-default-browser-check, serves loopback-only fixtures, and stops its own browser afterward. TLS/HTTP fingerprint equality was not measured.

@mandatoryprogrammer
mandatoryprogrammer merged commit a840a93 into main Oct 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant