supabase / auth-js

An isomorphic Javascript library for Supabase Auth.
MIT License
321 stars 153 forks source link

Stack guards not supported in this environment #746

Closed cyberkaidev closed 8 months ago

cyberkaidev commented 11 months ago

Bug report

Describe the bug

@supabase/gotrue-js: Stack guards not supported in this environment. Generally not an issue but may point to a very conservative transpilation environment (use ES2017 or above) that implements async/await with generators, or this is a JavaScript engine that does not support async/await stack traces.

To Reproduce

I was following the doc, I created the client and I was able to query the database, but a message keeps appearing in my app of:"@supabase/gotrue-js: Stack guards not supported in this environment. Generally not an issue but may point to a very conservative transpilation environment (use ES2017 or above) that implements async/await with generators, or this is a JavaScript engine that does not support async/await stack traces.". I'm using expo.

System information

atanaskanchev commented 11 months ago

+1 on that, it’s started happening after updating to the latest supabase-js version

mallahyari commented 11 months ago

Same here! have been working on for several hours, but still nothing!

j4w8n commented 11 months ago

Appears to be a harmless warning, where they've introduced stack traces for async/await?? I'm not familiar.

Bit of a description here: https://github.com/supabase/gotrue-js/pull/726

Also: Screenshot_20230720_012851_GitHub~2.jpg

isik-dev commented 11 months ago

I've got the same error after upgrading my expo SDK from 48 to 49. Warning appears regardless of @supabase/supabase-js version. Tested and was able to reporoduce in both:

saoud77 commented 11 months ago

Same here! I'm experiencing the same thing.

florianjuengermann commented 11 months ago

Same here!

Honest0 commented 11 months ago

Same here! I faced same issue on my vercel environment now.

insanrizky commented 11 months ago

Same here!

m1thrandir225 commented 11 months ago

Same here on Expo SDK 48 with @supabase/supabase-js "^2.24.0"

REDJEM-Amir commented 11 months ago

If the warning bothers you, you can remove it like this:

`const originalWarn = console.warn console.warn = (message, ...args) => { if (message.startsWith('@supabase/gotrue-js')) return originalWarn(message, ...args) }

import 'react-native-url-polyfill/auto' import * as SecureStore from 'expo-secure-store' import { createClient } from '@supabase/supabase-js';`

masnwilliams commented 11 months ago

It throws a full error for me and crashes my vercel deployment. I don't think the code above will help in this case.

j4w8n commented 11 months ago

It throws a full error for me and crashes my vercel deployment. I don't think the code above will help in this case.

Can you share the error and any other info you believe would be relevant?

masnwilliams commented 11 months ago

Can you share the error and any other info you believe would be relevant?

Of course, here is the error that is from my build logs on Vercel when trying to load my production build:

@supabase/gotrue-js: Stack guards not supported in this environment. Generally not an issue but may point to a very conservative transpilation environment (use ES2017 or above) that implements async/await with generators, or this is a JavaScript engine that does not support async/await stack traces. Safari is known to not support stack guards.

My entire application works perfectly on a preview build but fails once in production. When on the production build and I refresh the page, it flashes the correct ui for a split second and then I am hit with Application error: a server-side exception has occurred (see the server logs for more information)..

I have also confirmed that my production environment variables work completely fine in a staging build. It is just something with the build being production that throws gotrue for a loop.

For some additional context about my project: Framework: Next.js 13.4.12 @supabase/supabase-js: ^2.27.0 @supabase/gotrue-js: ^2.45.0 @supabase/auth-helpers-nextjs: ^0.7.3 Deployment: Vercel CI/CD: Github Actions (I only use this for my production build since I have some extra steps that need to run before I build the actual site)

Further Digging

This does not occur on pages where I do not call supabase.auth.getSession() from @supabase/auth-helpers-nextjs. I have this at the start of those pages which are react server components (not client-side):

const Page = async () => {
  const supabase = createServerComponentClient<Database>({ cookies })

  const {
    data: { session },
  } = await supabase.auth.getSession()

  // rest of page...

Maybe Vercel doesn't support Stack Overflow Guards resulting in this error but seems unlikely?

j4w8n commented 11 months ago

Roger. I should've been more clear. I thought Vercel would throw an additional log because you said it crashes.

masnwilliams commented 11 months ago

Yeah, that is the log that Vercel gives in my build log and the screenshot below is what my prod website looks like instead of loading the UI πŸ˜‚

Luckily this is a brand new product and has 0 users (like many of side projects lol) but I did use nextjs/vercel/supabase for a business I had before that had a lot of users and if something like this happened, I would be rolling back and considering switching to another cloud backend service.

Screenshot 2023-07-27 at 4 41 52 PM
j4w8n commented 11 months ago

This does not occur on pages where I do not call supabase.auth.getSession() from @supabase/auth-helpers-nextjs.

@masnwilliams I do see in the code where calling getSession() leads to a stack guard check or whatever. But there is also one when the client is initialized, so I'm not sure why it only chokes on those pages.

masnwilliams commented 11 months ago

@j4w8n Interesting update...

So I decided to remove my custom CI/CD GitHub Action pipeline that uses vercel deploy --prebuilt --prod --token=TOKEN and just run the build like a regular deploy on Vercel and everything works fine with no errors!

So I think it has to do with deploying a prebuilt build to vercel πŸ‘

Still narrowing it down and will respond again soon with final details

masnwilliams commented 11 months ago

Ok so I've narrowed this down to, at least in my case, a single cause.

It is the --prod flag on vercel deploy --prebuilt --prod --token=TOKEN.

Works:

Does Not Work:

Summarization

For some reason, Vercel Deploy Prod breaks the stack overflow guard that supabase gotrue auth implements.

So if you are deploying a project that uses Supabase Auth to Vercel using Vercel CLI, do not use the --prod tag. This ended up not being an issue for me because it seems like all the --prod tag does, at least from what I can see, is automatically set the build to direct to the production domain. Since I set my main repo branch to a specific domain, that solves that.

Hopefully this helps anyone who had this issue @atanaskanchev @mallahyari @saoud77 @florianjuengermann @Honest0 @insanrizky @m1thrandir225

EDIT: I was wrong...

So actually the issue, which makes way more sense, is the --prebuilt flag. A compiler issue could be the cause for this or some other weird build issue.

Another thing is that the --prod flag does not do what I thought it did. It actually sets the deployment as Production rather than just a preview.

So my fix is just using vercel --prod --token=TOKEN in my github workflow and it all works fine. This comes with the disadvantage of sending my code to vercel to be built rather than building before hand and then sending the "prebuilt" code to Vercel to deploy.

I will see if I can get a deploy working with the --prebuilt sometime later but now its time to get back to building πŸš€

m1thrandir225 commented 11 months ago

What about on expo? Is this something with the babel / typescript config on expo or ?

masnwilliams commented 11 months ago

What about on expo?

I'm not sure about this on expo. I am using Next.js so I can only speak for that unfortunately

abhishiv commented 11 months ago

This isnt an harmless error I think. It's also causing db queries to not work without any error in safari after you call supabase.auth.onAuthStateChange(). Anyone has a idea why?

This means supabase is broken on safari.

j4w8n commented 11 months ago

This isnt an harmless error I think. It's also causing db queries to not work without any error in safari after you call getSession(). Anyone has a idea why?

This means supabase is broken on safari.

I do see some references to safari in the helper functions, for code where they try to mitigate some safari issues. Maybe there are more needed??

If you can provide a minimum repo, or a code example, that might help out the maintainers.

abhishiv commented 11 months ago

Hey @j4w8n

Thanks for your reply. I'm using it like this

  supabase.auth.onAuthStateChange(async (event, session) => {
    console.log("sessions", event, session, session && session.user);
    if (session && session.user) {
      console.log("fetching");
      const { data, error } = await supabase
        .from("user_profiles")
        .select("*")
        .eq("id", session.user.id);
      console.log(data, error);
    } 
  });

The db query from user_profiles is silently swallowed and it never returns. This only happens on safari(I'm using v16.3) and it works without any issues in chrome.

dejongyeong commented 11 months ago

I have been dealing with this issue as well when using the latest packages to getSession() in middleware.ts after deploying to Vercel and testing it out with Chrome and Edge.

I found out that the older versions work but not the latest ones when deploying to Vercel after hours of testing and researching the error.

I have no choice at the moment but to downgrade the following packages:

"@supabase/auth-helpers-nextjs": "0.7.2",
"@supabase/gotrue-js": "2.34.0",
"@supabase/supabase-js": "2.26.0",

I will look back into this or upgrade to the latest version once it is more stable in Vercel Production.

virgiliud commented 11 months ago

I'm seeing the same error on Vercel.

@supabase/gotrue-js: Stack guards not supported in this environment. Generally not an issue but may point to a very conservative transpilation environment (use ES2017 or above) that implements async/await with generators, or this is a JavaScript engine that does not support async/await stack traces. Safari is known to not support stack guards.

masnwilliams commented 11 months ago

Supabase Auth team is looking into this now, hopefully we get a fix soon. It very likely could be related to using getSession() in middleware, which I do as well as @dejongyeong. However unlike @dejongyeong, reverting back to the versions mentioned did not solve my problem.

ryszardwhee commented 11 months ago

We are experiencing the same issue in production. We are hosting the code on vercel. The warning happens in middleware.ts when we call function: supabase.auth.refreshSession.

middleware.ts hang in production and timeouts.

Packages version: "next": "13.4.12", "@supabase/supabase-js": "^2.29.0"

dalkommatt commented 11 months ago

It throws a full error for me and crashes my vercel deployment. I don't think the code above will help in this case.

Same issue here with the same error in my Vercel logs: @supabase/gotrue-js: Stack guards not supported in this environment. Generally not an issue but may point to a very conservative transpilation environment (use ES2017 or above) that implements async/await with generators, or this is a JavaScript engine that does not support async/await stack traces. Safari is known to not support stack guards.

Using > ES2017 did not fix this issue for me.

"next": "^13.4.12", "supabase": "^1.82.2", "@supabase/auth-helpers-nextjs": "^0.7.3", "@supabase/supabase-js": "^2.31.0",

hf commented 11 months ago

Hey everyone, this is a warning. If you see it, your app should generally work as it worked many versions ago. It does mean that some new improvements to the library will probably not be supported. Please continue to report problems with it, but it does not mean that when you see this warning the behavior is because of it.

With regards to Expo: Expo uses WebKit which does not support async/await stack traces. Generally however in Expo / React Native / other WebKit based mobile app frameworks this can safely be ignored. I'll try to find a way to detect Expo / React Native and remove the log if it's bothering you.

With regards to Vercel, just seeing this now on supabase.com. This is a recent change as I am absolutely certain that 2 weeks ago stack guards worked.

@abhishiv Just seeing your problem. I suspect that does not work, because recently we made onAuthStateChange callbacks wait when notified before returning. Because stack guards are not supported on Safari / WebKit, the way you're using it may be causing async/await recursion and the callback is probably not completing. I'm trying to see if there's some other way this can be achieved to get rid of this issue. A quick fix could be, for example:

  supabase.auth.onAuthStateChange(async (event, session) => {
    console.log("sessions", event, session, session && session.user);
    if (session && session.user) {
      console.log("fetching");
      (async () => {
        const { data, error } = await supabase
          .from("user_profiles")
          .select("*")
          .eq("id", session.user.id);
        console.log(data, error);
       })()
    } 
  });

This will start the query outside the callback and the recursive wait should be gone.

abhishiv commented 11 months ago

hey @hf thanks for your reply!

Yeah, I was able to get around it with a similar technique using setTimeout.

  const handler = async (event: any | undefined, session: Session | null) => {
    if (session && session.user) {
      const { data, error } = await supabase
        .from("user_profiles")
        .select("*")
        .eq("id", session.user.id);
      if (error) {
        return;
      }
      const profile = data[0];
      $session({ session, profile });
    } else {
      $session(null);
    }
  };
  onMount(async () => {
    const session = await supabase.auth.getSession();
    handler(undefined, session.data.session);
    // https://github.com/supabase/gotrue-js/issues/746#issuecomment-1655484486
    setTimeout(() => supabase.auth.onAuthStateChange(handler), 0);
  });

However it would be great to have this behaviour documented since because of this issue I pushed a broken version in production and then had to spend a lot of time debugging it.

hf commented 11 months ago

pushed a broken version in production and then had to spend a lot of time debugging it.

Very sorry about this! I'm trying to find a way to fix this... Safari/WebKit is proving especially difficult. Also, please remember you can always revert back to the version that worked for you previously.

milovangudelj commented 11 months ago

I had the same issue with Next.js v13.4.12 and Supabase.js v2.31.0.

I got the error when I tried to use supabase in an edge function.

export const runtime = 'edge'

Removing it solved the issue.

iodamiano commented 11 months ago

I have the same error, on iOS i can start the project and having only the warning, if i try to launch the Web version crash all the things.

dmitryshostak commented 11 months ago

I think we've just encountered the same issue. Seems like Bing/Yahoo crawlers can't render our app. (Nextjs, Vercel, @supabase/auth-helpers-nextjs)

Request User Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/103.0.5060.134 Safari/537.36 Type: Edge Middleware

In Vercel logs also we get @supabase/gotrue-js: Stack guards not supported in this environment. Generally not an issue but may point to a very conservative transpilation environment (use ES2017 or above) that implements async/await with generators, or this is a JavaScript engine that does not support async/await stack traces.

hf commented 11 months ago

Hey everyone, I'm pushing hard to find a resolution to this. Would love your help in testing #757 if you're able to.

Please revert down to a version of this library that works for you.

milovangudelj commented 11 months ago

I'd be happy to test it out. How can I update the gotrue-js version used by supabase-js to try out the new implementation?

hf commented 11 months ago

@milovangudelj Usually you can use npm link or equivalents.

For example:

  1. Clone the repository.
  2. cd into it.
  3. npm i then npm run build
  4. npm link
  5. cd into your project
  6. npm link @supabase/gotrue-js
  7. When you build your project, it should pick up the cloned repo. However, this doesn't always work well so you might have to play around a few times to get it to work. Inspect all node_module directories in your project to see if gotrue-js links back to the cloned folder.
milovangudelj commented 11 months ago

Done that. It works on local, but I have no way of testing it on Vercel when deploying the app. There it's still going to pull the latest version and error out when deployed... Note that the error happens not during the build step but when invoking the api function containing both a Supabase client and export const runtime = 'edge'

kamto7 commented 11 months ago

Done that. It works on local, but I have no way of testing it on Vercel when deploying the app. There it's still going to pull the latest version and error out when deployed... Note that the error happens not during the build step but when invoking the api function containing both a Supabase client and export const runtime = 'edge'

Same to me. I don't know how this will affect the business.

silentworks commented 10 months ago

If you use yalc instead you can test this on Vercel.

For example:

milovangudelj commented 10 months ago

Ok, thanks! I'll try this later and I'll let you know how it goes ✌🏻

Diegofreema commented 10 months ago

I am having this same issue too with my expo project, it works in developement but crashes in production. i even had to install a previous version og supabase, but it still did not work.

makeusabrew commented 10 months ago

I've manually bumped my @supabase/gotrue-js dependency to v2.47.0 until https://github.com/supabase/supabase-js/pull/835 is merged. So far, so good. See my comment in that PR thread: https://github.com/supabase/supabase-js/pull/835#issuecomment-1701340535

picklebrownie commented 10 months ago

I am having this same issue. when the user submits the file, the error occurs.

code:

'use client'

import { Button } from '@/components/Button'
import { Input } from '@/components/Input'
import { Label } from '@/components/Label'
import { toast } from '@/components/UseToast'
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'
import { useRouter } from 'next/navigation'
import React, { useRef, useState } from 'react'
import { uuid } from 'uuidv4'

export default function UploadFile() {
  const supabase = createClientComponentClient()

  const [loading, setLoading] = useState(false)

  const [selectedFile, setSelectedFile] = useState<File | null>(null)
  const [fileValue, setFileValue] = useState<string>('')
  const [fileName, setFileName] = useState<string>('')

  const [fileAlias, setFileAlias] = useState<string>('')

  // Ref object to reference the input element
  const inputFile = useRef<HTMLInputElement>(null)

  // Handle file upload event
  async function uploadFile(event: React.FormEvent<HTMLFormElement>) {
    setLoading(true)
    event.preventDefault()

    const bucket = 'files'

    // check that a file exists
    if (!selectedFile) {
      // e.target.value = null
      setLoading(false)
      toast({
        variant: 'destructive',
        title: 'Oops...',
        description: 'No file found! Please try again.',
      })
      return
    }

    // get supabase user id
    const {
      data: { session },
    } = await supabase.auth.getSession()
    const userId = session?.user.id

    // add file to storage bucket

    const file_url = `${userId}/${uuid()}-${selectedFile.name}`

    // Call Storage API to upload file
    try {
      const { data: data2, error: error2 } = await supabase.storage
        .from(bucket)
        .upload(file_url, selectedFile)

      // Handle error if upload failed
      if (error2) {
        // console.log(
        //   'Documents > UploadFile > upload file error ',
        //   error2,
        // )
        // e.target.value = null
        toast({
          variant: 'destructive',
          title: 'Oops...',
          description: 'Error uploading the file! Please try again.',
        })
        setLoading(false)
        return
      }
    } catch (error) {
      toast({
        variant: 'destructive',
        title: 'Oops...',
        description: 'Error uploading the file! Please try again.',
      })
      setLoading(false)
      return
    }

    // add entry to user_files table
    const { data, error } = await supabase.from('user_files').insert({
      file_url: file_url,
      file_name: fileAlias,
      user_id: userId,
    })

    // Handle error if upload failed
    if (error) {
      // console.log(
      //   'Documents > UploadFile > upload record error ',
      //   error,
      // )
      // e.target.value = null
      toast({
        variant: 'destructive',
        title: 'Oops...',
        description: 'Error uploading the file! Please try again.',
      })
      setLoading(false)
      return
    }

    // redirect to dashboard/documents

    // handle what happens after the file is uploaded
    // event.target.value = null
    toast({
      title: 'Success!',
      description: 'File uploaded successfully!',
    })
    setFileAlias('')
    handleReset(event)
    setLoading(false)
  }

  const fileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    if (event.target.files && event.target.files.length > 0) {
      setSelectedFile(event.target.files[0])
    }
  }

  // Function to reset the input element
  const handleReset = (event: any) => {
    event.preventDefault()
    setSelectedFile(null)
    if (inputFile.current) {
      inputFile.current.value = ''
      inputFile.current.type = 'text'
      inputFile.current.type = 'file'
    }
  }
  return (
    <div>
      <div>
        <form
          onSubmit={uploadFile}
          id="form"
        >
          <div>
            <div className="mt-10 space-y-8 border-b border-gray-900/10 pb-12 sm:space-y-0 sm:divide-y sm:divide-gray-900/10 sm:border-t sm:pb-0">
              <div className="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-6">
                <Label htmlFor="alias">File Name</Label>
                <div className="mt-2 sm:col-span-2 sm:mt-0">
                  <Input
                    type="text"
                    name="alias"
                    value={fileAlias}
                    required
                    disabled={loading}
                    onChange={(e) => setFileAlias(e.target.value)}
                    placeholder="Appointment Bill 08/13/2023"
                    className="w-full sm:max-w-sm"
                  />
                </div>
              </div>
              <div className="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-6">
                <Label htmlFor="file">File</Label>
                <div className="mt-2 sm:col-span-2 sm:mt-0 flex flex-row">
                  <Input
                    type="file"
                    name="file"
                    ref={inputFile}
                    disabled={loading}
                    onChange={fileChange}
                    className="block w-full sm:max-w-sm"
                  />
                  {selectedFile && (
                    <Button
                      disabled={loading}
                      onClick={handleReset}
                      variant="secondary"
                      className="ml-4"
                    >
                      {loading ? 'Uploading...' : 'Remove File'}
                    </Button>
                  )}
                </div>
              </div>
            </div>
          </div>
          <div className="mt-6 flex items-center justify-end gap-x-6">
            <Button
              disabled={loading}
              type="submit"
            >
              {loading ? 'Uploading...' : 'Upload File'}
            </Button>
          </div>
        </form>
      </div>
    </div>
  )
}

error on vercel:

Request User Agent
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36
Level
Error

Environment
production
Branch
main
Type
Edge Middleware

Function
/middleware
@supabase/gotrue-js: Stack guards not supported in this environment. Generally not an issue but may point to a very conservative transpilation environment (use ES2017 or above) that implements async/await with generators, or this is a JavaScript engine that does not support async/await stack traces. Safari is known to not support stack guards.

Dashboard – Vercel

any help would be appreciated. this prevents my users from making uploads on mobile.

zohaib304 commented 10 months ago

I've updated to version @supabase/gotrue-js 2.51.0, and the issue is now resolved.

j4w8n commented 10 months ago

I've updated to version @supabase/gotrue-js 2.51.0, and the issue is now resolved.

Yeah I believe they went with a different mechanism for "locking", in a newer version.

0ax1 commented 9 months ago

I think this was resolved as part of https://github.com/supabase/gotrue-js/pull/757. @cyberkaidev Can this issue be closed?

amzamani commented 9 months ago

Same here, I am not getting the error in local development, but in the vercel logs of my serverless application