Skip to content

fix(realtime): tie channel join_ref to the actual join push ref - #1627

Merged
grdsdev merged 1 commit into
v3from
guilhermesouza/sdk-1526-join-ref-v3
Sep 17, 2026
Merged

grdsdev merged 1 commit into
v3from
guilhermesouza/sdk-1526-join-ref-v3

Conversation

@grdsdev

@grdsdev grdsdev commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #1626 for the v3 branch (different realtime implementation, same class of bug, different root cause).

RealtimeChannel.subscribe() sent the phx_join message with join_ref hardcoded to None, then set self.join_ref to a brand-new, unrelated ref generated after the join succeeded. Every later push on the channel (leave, broadcast, presence track/untrack) carried a join_ref that never matched any ref the server had actually seen for that channel — defeating its purpose of letting the server detect stale messages after a rejoin. Newer Phoenix versions rely on this and silently drop pushes that don't line up.

Fix: generate the join ref once in subscribe(), use it as both ref and join_ref on the phx_join message, and store that same value as channel.join_ref for subsequent pushes.

Test plan

  • Added tests/test_join_ref.py: a local in-process websocket server (same pattern as test_reconnection.py's RealtimeServer) records every client-sent message and asserts join/broadcast/track/untrack/leave all carry a join_ref equal to the actual phx_join ref. All 4 fail on unmodified v3 (confirmed) and pass after the fix.
  • ruff check / ruff format --check: clean.
  • mypy src/realtime tests: clean.
  • pytest tests/: the new tests plus the rest of the fast suite pass. test_connection.py/test_presence.py need a local Supabase stack and test_reconnection.py has a pre-existing port-reuse flake (address already in use on ::1:55555) — both reproduce identically on unmodified v3, unrelated to this change.

Fixes SDK-1526

RealtimeChannel.subscribe() sent the phx_join message with join_ref
hardcoded to None, then set self.join_ref to a brand-new, unrelated
ref generated *after* the join succeeded. Every later push on the
channel (leave, broadcast, presence track/untrack) therefore carried
a join_ref that never matched any ref the server had actually seen,
defeating its purpose: letting the server detect stale messages after
a rejoin. Newer Phoenix versions rely on this and silently drop
pushes that don't line up.

Fix: generate the join ref once, use it as both `ref` and `join_ref`
on the phx_join message, and store that same value as
channel.join_ref.

Fixes SDK-1526
@grdsdev
grdsdev requested review from a team and o-santi as code owners September 9, 2026 19:41
@grdsdev
grdsdev merged commit c082646 into v3 Sep 17, 2026
42 of 68 checks passed
@grdsdev
grdsdev deleted the guilhermesouza/sdk-1526-join-ref-v3 branch September 17, 2026 09:53
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