• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / supabase-flutter / 28190414303
85%

Build:
DEFAULT BRANCH: main
Ran 25 Jun 2026 06:06PM UTC
Jobs 8
Files 80
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

25 Jun 2026 06:04PM UTC coverage: 85.464% (+0.1%) from 85.368%
28190414303

push

github

web-flow
fix(realtime): surface async postgres_changes system error as channelError (#1470)

## Summary

Fixes #1466.

A `postgres_changes` channel can report
`RealtimeSubscribeStatus.subscribed` and stay joined while delivering
**zero** events, indefinitely, when the server-side replication
subscription fails *after* the phoenix join succeeds. The failure is
delivered as an asynchronous `system` event with `status: error`, but
the SDK only exposes that via `onSystemEvents(...)` (documented "for
debugging purposes") and never forwards it to the `.subscribe()` status
callback — a silent "zombie" channel: green/connected to the app, but
dead.

This is especially painful on reconnect/resume flows where the access
token may be stale (e.g. the refresh timer was throttled while the app
was idle/backgrounded). The channel re-subscribes, the join succeeds,
the app marks it healthy, and it silently delivers nothing until the
next reconnect. It bit us as a user-facing incident: live data silently
stopped updating after a reconnect.

## Root cause

`postgres_changes` is an extension whose replication subscription is set
up asynchronously by the server, *after* the channel join.
`.subscribe()`'s status is driven by the phoenix join
(`joined/errored/closed/timeout`), and there is no
`RealtimeSubscribeStatus` value for "joined, but the extension
subscription failed." The join reply optimistically echoes the requested
`postgres_changes` config (with server-assigned binding ids), so binding
reconciliation succeeds and `subscribed` fires *before* the replication
is confirmed live. The real verdict arrives on a later `system
status=error` event, which the high-level API drops on the floor.

Wire sequence with a **stale/expired** token (`auth.uid()` no longer
satisfies the policy):

```
<- phx_reply   status=ok    response={postgres_changes:[{id, event:INSERT, schema, table, filter}]}
   // subscribe() callback fires RealtimeSubscribeStatus.subscribed here
<- system      status=... (continued)

4 of 4 new or added lines in 1 file covered. (100.0%)

4098 of 4795 relevant lines covered (85.46%)

3.64 hits per line

Jobs
ID Job ID Ran Files Coverage
6 supabase - 28190414303.6 25 Jun 2026 06:06PM UTC 15
81.99
GitHub Action Run
7 supabase_flutter - 28190414303.7 25 Jun 2026 06:07PM UTC 11
77.52
GitHub Action Run
8 realtime_client - 28190414303.8 25 Jun 2026 06:08PM UTC 11
88.5
GitHub Action Run
5 storage_client - 28160249676.5 25 Jun 2026 09:26AM UTC 5
92.97
GitHub Action Run
4 functions_client - 27986095786.4 22 Jun 2026 09:45PM UTC 2
97.14
GitHub Action Run
7 yet_another_json_isolate - 27986095786.7 22 Jun 2026 09:45PM UTC 1
79.03
GitHub Action Run
4 gotrue - 28160249676.4 25 Jun 2026 09:26AM UTC 26
84.05
GitHub Action Run
7 postgrest - 28160249676.7 25 Jun 2026 09:26AM UTC 9
84.05
GitHub Action Run
Source Files on build 28190414303
  • Tree
  • List 80
  • Changed 7
  • Source Changed 7
  • Coverage Changed 6
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #28190414303
  • d1271701 on github
  • Prev Build on main (#28177869575)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc