Skip to content

fix(realtime): include join_ref on every client-sent channel event - #1626

Merged
grdsdev merged 1 commit into
mainfrom
guilhermesouza/sdk-1526-check-join_ref-handling-in-python-realtime-sdk
Sep 17, 2026
Merged

grdsdev merged 1 commit into
mainfrom
guilhermesouza/sdk-1526-check-join_ref-handling-in-python-realtime-sdk

Conversation

@grdsdev

@grdsdev grdsdev commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

AsyncPush.send() built outgoing Messages with only ref, leaving join_ref permanently null. The Realtime protocol requires join_ref on every client-sent event (join, leave, broadcast, presence track/untrack) so the server can detect stale messages after a rejoin; newer Phoenix versions rely on it and silently drop pushes that omit it — this matches the track/untrack timeout reports that motivated this check.

Fix: AsyncPush.send() now sets join_ref=self.channel.join_push.ref when building the outgoing message.

Test plan

  • Added tests/test_join_ref.py (5 tests): join carries join_ref == ref, broadcast/track/untrack carry the channel's join_ref, leave carries the pre-leave join_ref, rejoin produces a fresh join_ref.
  • ruff check / ruff format --check: clean.
  • mypy src/realtime tests: clean.
  • pytest tests/: 25 passed, 6 failed — the 6 failures need a local Supabase stack (127.0.0.1:54321) and fail identically on main, unrelated to this change.

Fixes SDK-1526

AsyncPush.send() built outgoing Messages with only `ref`, leaving
`join_ref` permanently null. The Realtime protocol requires join_ref
on every client-sent event (join, leave, broadcast, presence
track/untrack) so the server can detect stale messages after a
rejoin; newer Phoenix versions rely on it and silently drop pushes
that omit it (matches the track/untrack timeout reports in SDK-1526).

Fixes SDK-1526
@grdsdev
grdsdev requested review from a team and o-santi as code owners September 9, 2026 19:32
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

⚠️ Capability matrix drift detected

The following capabilities are marked implemented in the matrix but could not be found in python:

  • database.configuration.auto_retry → expected symbol: AsyncSelectRequestBuilder.retry
  • database.configuration.auto_retry → expected symbol: SyncSelectRequestBuilder.retry
  • realtime.client.connect → expected symbol: SyncRealtimeClient.connect
  • realtime.client.disconnect → expected symbol: AsyncRealtimeClient.disconnect
  • realtime.client.disconnect → expected symbol: SyncRealtimeClient.disconnect
  • realtime.channel.subscribe → expected symbol: SyncRealtimeChannel.subscribe
  • realtime.channel.unsubscribe → expected symbol: SyncRealtimeChannel.unsubscribe
  • realtime.channel.broadcast → expected symbol: SyncRealtimeChannel.send_broadcast
  • realtime.subscriptions.broadcast → expected symbol: SyncRealtimeChannel.on_broadcast
  • realtime.subscriptions.postgres_changes → expected symbol: SyncRealtimeChannel.on_postgres_changes
  • realtime.subscriptions.subscribe_presence → expected symbol: AsyncRealtimeChannel.on_presence_change
  • realtime.subscriptions.subscribe_presence → expected symbol: SyncRealtimeChannel.on_presence_change
  • realtime.presence.track → expected symbol: SyncRealtimeChannel.track
  • realtime.presence.untrack → expected symbol: SyncRealtimeChannel.untrack
  • realtime.presence.presence_state → expected symbol: AsyncRealtimeChannel.presences
  • realtime.presence.presence_state → expected symbol: SyncRealtimeChannel.presences

The following capabilities are marked implemented in python but have no registered symbols to verify:

  • auth.session.auto_refresh (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.cross_client_token_sync (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.oauth_flow_type (no symbols list — cannot confirm implementation exists)
  • client.session_management.custom_storage (no symbols list — cannot confirm implementation exists)
  • client.session_management.persist_session (no symbols list — cannot confirm implementation exists)
  • client.request_configuration.custom_http_client (no symbols list — cannot confirm implementation exists)
  • client.request_configuration.global_headers (no symbols list — cannot confirm implementation exists)
  • database.mutate.select_after_mutation (no symbols list — cannot confirm implementation exists)
  • database.using_filters.eq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.neq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike (no symbols list — cannot confirm implementation exists)
  • database.using_filters.is (no symbols list — cannot confirm implementation exists)
  • database.using_filters.in (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contains (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contained_by (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_adjacent (no symbols list — cannot confirm implementation exists)
  • database.using_filters.overlaps (no symbols list — cannot confirm implementation exists)
  • database.using_filters.text_search (no symbols list — cannot confirm implementation exists)
  • database.using_filters.match (no symbols list — cannot confirm implementation exists)
  • database.using_filters.not (no symbols list — cannot confirm implementation exists)
  • database.using_filters.or (no symbols list — cannot confirm implementation exists)
  • database.using_filters.raw (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex_icase (no symbols list — cannot confirm implementation exists)
  • database.using_filters.not_in (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.order (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.limit (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.range (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.request_cancellation (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.relationship_embed (no symbols list — cannot confirm implementation exists)
  • database.configuration.request_timeout (no symbols list — cannot confirm implementation exists)
  • functions.invocation.region_selection (no symbols list — cannot confirm implementation exists)
  • functions.invocation.request_cancellation (no symbols list — cannot confirm implementation exists)
  • functions.invocation.timeout (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.postgres_changes_filter (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.private_channel (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_self (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_replay (no symbols list — cannot confirm implementation exists)
  • realtime.presence.presence_key (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.heartbeat_interval (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.access_bucket (no symbols list — cannot confirm implementation exists)

These may have been renamed, removed, or never registered. Please update the capability matrix.
See: https://github.com/supabase/sdk/blob/main/packages/capability-matrix/docs/capability-matrix.md

@grdsdev
grdsdev merged commit 8c1a914 into main Sep 17, 2026
46 checks passed
@grdsdev
grdsdev deleted the guilhermesouza/sdk-1526-check-join_ref-handling-in-python-realtime-sdk branch September 17, 2026 09:49
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