supabase/supabase-js

Suddenly getting 'subscribe' can only be called a single time per channel instance` when deployed on Vercel

Closed this issue · 10 comments

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

Suddenly getting Tried to subscribe multiple times. 'subscribe' can only be called a single time per channel instance when deployed on Vercel. Works fine on local.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Vercel deployment.
  2. Use subscribe on useEffect
    Code Sample:
    useEffect(() => {
      refetch()


        const channel = supabase
          .channel('realtime:notification-channel')
          .on(
            'postgres_changes',
            { event: 'INSERT', schema: 'public', table: 'notifications' },
            (payload) => {
              if (user && user.id === payload.new.userId) {
                setUnseen(unseen + 1)
                refetch()
              }
            },
          )
          .subscribe()

        return () => {
          supabase.removeChannel(channel)
        }

    }, [])

Expected behavior

Doesn't crash the app.

System information

  • Vercel deployment
  • Version of supabase-js: [latest]
  • Next.js version: 15.3.3

Additional context

  • This wasn't throwing errors a few days before. I added a try catch block around it for now.
  • I noticed removeChannel() returns a promise but subscribe() does not so it might be a race condition like subscribing before being removed. So I moved channel setup to an async function as well.
  • Just want to confirm if the behavior recently changed (here or supabase realtime)

I also have started to see this.

UPDATE: i pulled up a hook that was subscribing to the same channel/filter from multiple components and that fixed it for me. I thought it was meant to handle that, but maybe there is a race condition.

I started seeing the same issue (works locally, fails on Vercel) around the same time. I wonder if it is a Vercel issue.

I had a build that was working great on June 5. I pushed a number of changes on June 8 and started seeing that error for the first time. I can't get anything after June 8 to run without the error and the Vercel build on June 5 runs great when I (re)promote it. I have tried rolling back all the changes little by little to match the June 5 build and I keep encountering the error. I wonder if the issue is that something changed in the way that Vercel is building.

It's frustrating as I'm not able to able to maintain or update my application until I get this sorted.

Will look again for duplicated listeners... but it is strange to see an error like this materialize with the same package versions.

I'm running into the same issue after upgrading from 2.48.1 to 2.50.0 so I had to revert. We're you able to find a workaround? It's possible this is an issue with the way this works within a react useEffect hook. For what it's worth I'm calling unsubscribe in the useEffect return rather than removeChannel, did that make a difference for you?

I am seeing a similar problem in my react native implementation, I am currently using 2.50.0:

useEffect(() => {
    if (!user) return

    const walletChannel = supabase.channel('wallet-update-channel')
      .on(
        'postgres_changes',
        { event: 'UPDATE', schema: 'public', table: 'wallet', filter: `user=eq.${user?.id}` },
        (payload) => {
          if (payload.new) {
            const response = payload?.new as Tables<'wallet'>
            setLocalWalletBalance(response.balance ?? 0)
            
            if (response.balance! > wallet?.balance!) {
              Toast.show({
                type: 'info',
                text1: 'Wallet funded successfully.'
              })
              Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success)
            }

            queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.getLatestTransactions] })
            queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.getTransactions] })
            queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.getWalletBalance] })
          }
        }
      )

    walletChannel.subscribe()

    // supabase.removeChannel(walletChannel)

    return () => { 
      supabase.removeChannel(walletChannel)
    }
  }, [user?.id, wallet?.balance])

Hi, we had a few changes on https://github.com/supabase/realtime-js/releases/tag/v2.11.8 that could impact this behavior, we'll be taking a look to check if there are any issues on our side.

Thanks.

Same problem.

"expo": "~53.0.10",
"@supabase/supabase-js": "^2.50.0",
"@tanstack/react-query": "^5.80.6",

Same issue here.

    "@supabase/supabase-js": "^2.50.0",

Hi all, could you try out the v2.50.1-next.6 version and let me know if that fixes your issue?

Thanks.

Hi all, could you try out the v2.50.1-next.6 version and let me know if that fixes your issue?

Thanks.

Issue not resolved.

Warning: tried to subscribe multiple times. 'subscribe' can only be called a single time per channel instance

"expo": "53.0.12",
"@supabase/supabase-js": "^2.50.1-next.6",
"@tanstack/react-query": "^5.80.7",

My code

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
storage: new LargeSecureStore(),
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
});

useEffect(() => {
if (!userId) return;

const channelName = `test-channel`;

const subscription = supabase
  .channel(channelName)
  .on(
    "postgres_changes",
    {
      event: "UPDATE",
      schema: "public",
      table: "test",
      filter: `eq.user_id.${userId}`,
    },
    (payload) => {
      console.log("payload", payload);

      queryClient.invalidateQueries({
        queryKey: [queryKeys.test.all],
      });
    }
  )
  .subscribe();

return () => {
  supabase.removeChannel(subscription);
};

}, [userId]);

Hi this has been fixed on latest version of the library, please let me know if you're still facing this after update.