Skip to content

VAPI-3917 fix(signaling): only retry on close code 1001, tear down on everything else - #19

Merged
smoghe-bw merged 2 commits into
mainfrom
fix/no-retry-on-superseded-close
Sep 9, 2026
Merged

VAPI-3917 fix(signaling): only retry on close code 1001, tear down on everything else#19
smoghe-bw merged 2 commits into
mainfrom
fix/no-retry-on-superseded-close

Conversation

@smoghe-bw

@smoghe-bw smoghe-bw commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Jira: VAPI-3802

The problem

rpc-websockets is built with unlimited auto-reconnect. Its own internal check only special-cases close code 1000 — every other code, including ones this SDK has never heard of, gets retried forever. A server can legitimately want to reject a reconnect permanently with some other close code, and today's client would just keep hammering it.

The fix

Flip the default from a deny-list to an allow-list. 1001 (Going Away) is the only code that means "come back on this exact session." Every other code — 1000 (session over for good), 1011 (internal error, where retrying this same connection isn't the right recovery), 4409, and anything unrecognized — now disables auto-reconnect and tears the connection down instead of silently retrying.

Disabling auto-reconnect alone isn't enough for codes other than 1000: rpc-websockets decides whether to schedule a reconnect synchronously, inside the raw WebSocket's own close listener, before it even fires the close event this file listens on (that emit is deferred). By the time our handler runs, the reconnect timer is already queued, so it's cleared directly via the client's reconnect_timer_id.

Test plan

  • tsc --noEmit clean
  • jest — 155/155 pass, including new cases for 1001 (retries) and 4409/1011/an unrecognized code (all tear down and disable auto-reconnect)

🤖 Generated with Claude Code

…g else

rpc-websockets' unlimited auto-reconnect only special-cases close code
1000 - every other code, including ones this SDK doesn't recognize yet,
was silently retried forever. Flip the default: 1001 (Going Away) is
the only code the gateway sends to mean "come back on this session";
everything else - 1000 (endpoint gone), 4409 (superseded by a newer
connection from this same device, pv-gateway PR pv-gateway#123), 1011
(internal error, where the right recovery is minting a new endpoint,
not retrying this connection), and any future/unknown code - now
disables auto-reconnect and tears the connection down.

The gateway-initiated codes (4409, 1011) race the "close" event: the
underlying client schedules its reconnect timer synchronously inside
the raw WebSocket's own close listener, before it defers emitting the
"close" event this file listens on. setAutoReconnect(false) alone is
too late for those; the already-queued reconnect_timer_id has to be
cleared directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@smoghe-bw
smoghe-bw requested review from a team as code owners September 9, 2026 18:23
@bwappsec

bwappsec commented Sep 9, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Drop pv-gateway internal implementation detail (drain eviction, media
server loss, etc.) from comments — this is a public SDK, comments
should describe SDK behavior, not the internals of one server that
happens to implement the protocol.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@smoghe-bw smoghe-bw changed the title fix(signaling): only retry on close code 1001, tear down on everything else VAPI-3917 fix(signaling): only retry on close code 1001, tear down on everything else Sep 9, 2026
@smoghe-bw
smoghe-bw merged commit 541c123 into main Sep 9, 2026
5 checks passed
@smoghe-bw
smoghe-bw deleted the fix/no-retry-on-superseded-close branch September 9, 2026 18:56
stampercasey added a commit that referenced this pull request Sep 10, 2026
…w retry-code policy

origin/main (VAPI-3917, #19) narrowed rpc-websockets' auto-reconnect to close
code 1001 only, tearing down on 1000/4409/1011/unknown instead of retrying
them forever. That is a different layer than this branch touches - it decides
whether the underlying client reconnects at all, while republishStreams()
only runs once it has and "init" re-fires - and the two coexist without
overlap: FATAL_HANDSHAKE_ERRORS/fatalError fires on a rejected upgrade before
any socket exists, RETRY_CLOSE_CODES fires on a close after a successful one.

pv-gateway sends 1001 (Going Away) for every retryable teardown (drain
eviction, media-server loss, instance shutdown), so it stays in
RETRY_CLOSE_CODES and this branch's fix keeps firing on exactly the paths it
was built for.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

3 participants