Skip to content

fix(server): probe a tab before reticle open reuses it - #665

Closed
kushals256 wants to merge 2 commits into
reticlehq:mainfrom
kushals256:fix/open-wedged-tab
Closed

fix(server): probe a tab before reticle open reuses it#665
kushals256 wants to merge 2 commits into
reticlehq:mainfrom
kushals256:fix/open-wedged-tab

Conversation

@kushals256

@kushals256 kushals256 commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • reticle open reused any connected tab on the origin, including ones that had stopped answering. reticle_session end only dropped the session record — the wedged page stayed in the daemon's browser, so the next open handed it back and every command timed out. Recovery required restarting the daemon.
  • open now probes the candidate with a short snapshot/status before reuse. Silence → open a fresh tab and say so. An older daemon without POST /session-probe 404s and is treated as live, which is the previous behaviour.
  • Only the tab that would actually be reused is probed, so a live tab stays a millisecond round-trip.

Closes #593.

Test plan

  • A connected tab that answers is still reused (no extra browser window)
  • A connected tab that does not answer a 1.5s snapshot is not reused; open launches a new one and reports replacing
  • reticle_session end on a wedged tab is no longer the only (broken) recovery — open recovers without a daemon restart
  • An older daemon that 404s on /session-probe still reuses (fail open)
  • @reticlehq/server unit tests for decideOpen / resolveOpen / POST /session-probe

Comment thread packages/server/src/cli/cli-launch.ts Fixed
Comment on lines +204 to +211
{
host: LOOPBACK_HOST,
port,
path: SESSION_PROBE_PATH,
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) },
timeout: SESSION_PROBE_HTTP_TIMEOUT_MS,
},
A connected session can sit in /status while answering nothing, and
ending it only drops the bookkeeping — the wedged page is the daemon's
browser. Probe the candidate with a short snapshot; if it does not
answer, open a fresh tab. An older daemon without the probe route is
treated as live, which is the previous behaviour.

Signed-off-by: Kushal S <skushal.mys@gmail.com>
CodeQL flagged the probe request because the HTTP path was a parameter
flowing into http.request. The path is SESSION_PROBE_PATH and never
anything else; pin it at the call, matching fetchStatus.

Signed-off-by: Kushal S <skushal.mys@gmail.com>
@divshekhar

Copy link
Copy Markdown
Contributor

Superseded — #593 was fixed on main in ff02ea2a ("stop handing back a tab that has stopped answering", 2026-08-28) and shipped in v2.13.1. decideOpen filters unresponsive sessions before any reuse decision, with the reasoning written into the comment: open is the command a caller reaches for to RECOVER, so reusing the wedged tab left no way out short of killing the daemon.

Nothing left to merge. Apologies for the wasted cycle.

@divshekhar divshekhar closed this Sep 8, 2026
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.

reticle open reuses a connected-but-wedged tab instead of opening a fresh one

3 participants