Skip to content

fix(supabase): avoid dropping realtime auth to manual mode on client init - #2464

Open
hmnd wants to merge 4 commits into
supabase:masterfrom
hmnd:push-svuxpxprzxwv
Open

fix(supabase): avoid dropping realtime auth to manual mode on client init#2464
hmnd wants to merge 4 commits into
supabase:masterfrom
hmnd:push-svuxpxprzxwv

Conversation

@hmnd

@hmnd hmnd commented Jun 20, 2026

Copy link
Copy Markdown

🔍 Description

When using a custom callback for accessToken on SupabaseClient, realtime gets stuck on the access token initially set during init, rather than refreshing from the callback as expected.

What changed?

I've replaced the previous approach of manually requesting the accesstoken inside SupabaseClient's constructor with an empty call to realtime.setAuth(). This way realtime retrieves and sets the access token on its own, without dropping to manual mode.

Why was this change needed?

I ran into this issue with my custom minted jwts. I found #1304, in which the fix was to manually call supabase.realtime.setAuth() with no args to re-enable callback mode for access tokens.

I also couldn't find any documentation advising users of custom tokens that they must always call do this after client init, making for poor UX and confusing bugs.

Closes #1304

🔄 Breaking changes

Technically not a breaking change but, with this change, we do lose the Failed to set initial Realtime auth token error message if the accessToken function throws, because realtime's setAuth has its own error handling.

  • This PR contains no breaking changes

📋 Checklist

  • I have read the Contributing Guidelines
  • My PR title follows the conventional commit format: <type>(<scope>): <description>
  • I have run pnpm nx format to ensure consistent code formatting
  • I have added tests for new functionality (if applicable)
  • I have updated documentation (if applicable)

📝 Additional notes

#1304 really shouldn't have been closed and that is what frustrates me about stale bots. I would kindly suggest reconsidering the repo's usage of stale bot, or altering its config to eg. re-open issues if commented on after auto-close.

@hmnd
hmnd requested a review from a team as a code owner June 20, 2026 23:40

@mandarini mandarini left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @hmnd, thank you so much for contributing to Supabase! This is a great catch, and the root cause diagnosis is spot on. Confirmed that setAuth(token) with an explicit value flips realtime into manual mode for good, which is exactly why refresh was getting stuck for custom JWT callbacks. Really appreciate you digging into this instead of just settling for the workaround from #1304.

Two small things before we merge:

  1. Could you add a .catch() back on the this.realtime.setAuth() call in the constructor? Right now a failure there would be an unhandled promise rejection rather than a caught error.
  2. A few months ago we specifically wrapped this same call in Promise.resolve() to fix a Firefox extension cross-context Promise error (#2033). Since this PR removes that wrap, could you double check (or let us know your reasoning on) whether that issue could resurface here?

Thank you again for taking the time to fix this properly instead of just leaving the workaround in place. Contributions like this are what keep our SDKs solid.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 66c88832-3e7f-4dfd-8d1a-0d22e4117df4

📥 Commits

Reviewing files that changed from the base of the PR and between 6331898 and 51b3648.

📒 Files selected for processing (2)
  • packages/core/supabase-js/src/SupabaseClient.ts
  • packages/core/supabase-js/test/unit/SupabaseClient.test.ts

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved Realtime authentication initialization when using access-token callbacks.
    • Preserved callback mode after token retrieval errors, allowing authentication to be retried.
    • Improved handling of asynchronous token setup during client initialization.

Walkthrough

SupabaseClient now starts Realtime authentication by calling realtime.setAuth() directly, delegating access-token resolution to the Realtime client. Unit tests verify successful callback-based token initialization, token capture, and retention of callback mode when the access-token callback fails.

Assessment against linked issues

Objective Addressed Explanation
Automatically propagate the authenticated session token to Realtime without requiring an explicit setAuth call [#1304]

Possibly related PRs

Suggested labels: realtime-js


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hmnd

hmnd commented Jul 30, 2026

Copy link
Copy Markdown
Author

@mandarini thanks for the review!

Regarding your comments:

  1. I've re-added the catch, though realistically, it likely won't ever catch anything since everything within setAuth is contained in a giant try/catch
  2. The Promise.resolve wrapping is no longer needed because (as I understand it) the original issue stemmed from this.accessToken() being called in a different context from where it was defined. We no longer call this.accessToken() from within the constructor - instead only awaiting it within realtime.setAuth, where it has never caused such context-crossing issues. Not to mention, we're not doing a .then anymore either.

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.

Realtime RLS does not work if I don't explicitly setAuth

2 participants