next.js icon indicating copy to clipboard operation
next.js copied to clipboard

NextJS 14.2.4 With-Supabase Build Error - Error: `cookies` was called outside a request scope.

Open KyleAESI opened this issue 1 year ago • 7 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.5.0: Wed May  1 20:12:58 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6000
  Available memory (MB): 16384
  Available CPU cores: 10
Binaries:
  Node: 20.5.1
  npm: 10.3.0
  Yarn: 1.22.22
  pnpm: N/A
Relevant Packages:
  next: 14.2.4 // Latest available version is detected (14.2.4).
  eslint-config-next: 13.0.0
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which example does this report relate to?

with-supabase

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

next build

Describe the Bug

Running into a bug in my project. I'm trying test a build locally before building my app into a docker container. I continuing to get the same build error response:

  ▲ Next.js 14.2.4
  - Environments: .env

   Creating an optimized production build ...
 ✓ Compiled successfully
 ✓ Linting and checking validity of types
   Collecting page data  ..Error: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context
    at getExpectedRequestStore (/Users/aesi-kylem/Documents/Gitlab/testing-build/node_modules/next/dist/client/components/request-async-storage.external.js:28:11)
    at u (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/chunks/544.js:10:3754)
    at a (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/app/page.js:1:4507)
    at 1903 (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/app/page.js:1:4014)
    at t (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/webpack-runtime.js:1:128)
    at 9729 (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/app/page.js:1:1631)
    at t (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/webpack-runtime.js:1:128)
    at r (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/app/page.js:1:5582)
    at /Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/app/page.js:1:5621
    at t.X (/Users/aesi-kylem/Documents/Gitlab/testing-build/.next/server/webpack-runtime.js:1:1206)

> Build error occurred
Error: Failed to collect page data for /
    at /Users/aesi-kylem/Documents/Gitlab/testing-build/node_modules/next/dist/build/utils.js:1268:15
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  type: 'Error'
}
   Collecting page data  .error: script "build" exited with code 1

I'm using the with-supabase template and this error is suggesting a mishandling of the cookies call which is giving the out of scope error. The error seems to bounce from the root / page and my /projects. Both are a fairly standard setup of a page.tsx server async component (default) awaiting fetches from a "use server" actions file that fetches from my supabase DB and passes the data down to client components as props.

Simplified Page.tsx minus the props client pass:

// app/page/page.tsx

import { getLatestProjects } from "@/libs/actions/actions";

async function Page() {
const projects = await getLatestProjects();
return (
 <main className="flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-8 max-w-[90vw] mx-auto">
   <ul className=" text-black">
     {projects?.map((project) => (
       <li key={project.id}>{project.name}</li>
     ))}
   </ul>
 </main>
);
}

export default Page;

actions.ts:

"use server"

import { createClient } from "@/utils/supabase/server";

const supabase = createClient();

export async function getLatestProjects() {
    let { data: projects, error } = await supabase
  .from('new_projects')
  .select('*')
  .order('end_date', { ascending: false })
  .limit(10);

    if (error) throw error;

    return projects;
}

To troubleshoot I created a fresh new project using npx create-next-app -e with-supabase and copied over only my .env file and the simplified code you see above to test. When running next build i get the same error.

Expected Behavior

No error should be present when running next build with this project, especially, with no extra config changes to any of the boilerplate auth/session/cookie handling code in the with-supabase,

To Reproduce

  1. Pull down or create a fresh Next app using the with-supabase example: npx create-next-app -e with-supabase

  2. Rename the .env.example to .env and provide your NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY

NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
  1. Create a table with some dummy data of at least id and name. Create an actions file in /lib/actions/actions.ts. Paste the below fetch using the supabase client to your dummy data:
import { createClient } from "@/utils/supabase/server";

const supabase = createClient();

export async function getTest() {
    let { data: test, error } = await supabase
  .from('**your_db**')
  .select('*')
  .limit(10);

    if (error) throw error;

    return test;
}
  1. Remove all boilerplate content from app/page.tsx and replace with the following:
// app/page/page.tsx

import { getTest } from "@/libs/actions/actions";

async function Page() {
  const tests = await getTest();
  return (
    <main className="flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-8 max-w-[90vw] mx-auto">
      <ul className=" text-black">
        {tests?.map((test) => (
          <li key={test.id}>{test.name}</li>
        ))}
      </ul>
    </main>
  );
}

export default Page;

  1. Test that the app runs with next dev and that your dummy data shows on page at http://localhost:3000/
  2. Finally, run next build, this is where it will error our citing Collecting page data ..Error: cookies was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context

KyleAESI avatar Jun 25 '24 18:06 KyleAESI

I am also facing same issue, have you been able to resolve this problem?

Taofeekabdulazeez avatar Jun 28 '24 08:06 Taofeekabdulazeez

hmm i am also getting the same error when using supabase/server.ts

import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'

export function createClient() {
  const cookieStore = cookies()

  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            cookieStore.set(name, value, options),
          )
        },
      },
    },
  )
}

It happens when i am making a stripe webhook call and want to save user's data in supabase, it is working fine it i directly use supabase

import { createClient } from '@supabase/supabase-js'


const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
)

Ansub avatar Jun 29 '24 16:06 Ansub

I have encountered the same problem. What is strange this problem occurs with me only on a specific route. On other route pages where I have basically almost identical logic the problem does not occur.

Interestingly - With the same code, a week ago, everything worked. Isn't this a problem maybe with Supabase?

I'm using Next 14.2.3 Problem occurs on local server - npm run dev

therobertos007 avatar Jun 29 '24 17:06 therobertos007

I was having a similar issue, I was able to fix it by ensuring that my createClient() statements are within the functions of my code. For example, your actions.ts should be updated to the below:

Actions.ts

"use server"

import { createClient } from "@/utils/supabase/server";

export async function getLatestProjects() {
  const supabase = createClient();
    let { data: projects, error } = await supabase
  .from('new_projects')
  .select('*')
  .order('end_date', { ascending: false })
  .limit(10);

    if (error) throw error;

    return projects;
}

robskinney avatar Jun 30 '24 13:06 robskinney

I have encountered the same problem. What is strange this problem occurs with me only on a specific route. On other route pages where I have basically almost identical logic the problem does not occur.

Interestingly - With the same code, a week ago, everything worked. Isn't this a problem maybe with Supabase?

I'm using Next 14.2.3 Problem occurs on local server - npm run dev

Interesting, I haven't had the issue in dev so far, just the build step. Which I needed to work in order to build a docker container for hosting but also would assume I would get errors if I pushed to Vercel or others.

I'm on 14.2.4 but when i started this project I think it was 14.2.1. As well, I have used both NPM and Bun, with and without turbopack enabled.

KyleAESI avatar Jul 02 '24 13:07 KyleAESI

I was having a similar issue, I was able to fix it by ensuring that my createClient() statements are within the functions of my code. For example, your actions.ts should be updated to the below:

Actions.ts

"use server"

import { createClient } from "@/utils/supabase/server";

export async function getLatestProjects() {
  const supabase = createClient();
    let { data: projects, error } = await supabase
  .from('new_projects')
  .select('*')
  .order('end_date', { ascending: false })
  .limit(10);

    if (error) throw error;

    return projects;
}

Hmm, this makes sense. Prior to posting here I did run a bunch of google searches and the only thread or mention I could find did talk about making sure my cookies() call was inside my function. But I was not directly using that anywhere in my app. However I didn't think about that pass down of the cookies that are called in the supabase client.

I will give this a shot, I did already find a workaround of sorts. I just moved all the calls to my Page.tsx component rather than refactoring to the actions file. This works but was still puzzled as to why a pattern I have used everywhere else seemingly was not allowed?

Thanks for the suggestion! I will update if that works for me.

KyleAESI avatar Jul 02 '24 13:07 KyleAESI

Ok I also fixed my problem

Here is how my action.ts looks like now

"use server";

import { createClient } from "@/utils/supabase/server";

export async function getAllClients() {
  const supabase = createClient();

  const { data } = await supabase.from("profiles").select();

  return data ?? [];
}

export async function getSpecificClient(clientId: string) {
  const supabase = createClient();

  const { data } = await supabase
    .from("profiles")
    .select()
    .eq("id", clientId)
    .single();

  return data;
}

In a previous version of this file, I declared const supabase = createClient() once right after importing the file. Unfortunately, the initialization of the supabase has to be done separately inside each exported function. I don't like such duplication of code 😢

therobertos007 avatar Jul 02 '24 19:07 therobertos007

can confirm that the problem is in fact usage of createClient() out of function scope aka usage as global variable.

logemann avatar Jul 13 '24 16:07 logemann

yea the soln is just to find any where you called createClient that is not inside a function , dont call your createClient in a global scope

urah001 avatar Jul 16 '24 13:07 urah001

How does it work with unit testing though? How do you unit test those functions, if cookies aren't available when running unit test with e.g. jest?

antonio-bluco avatar Jul 24 '24 08:07 antonio-bluco

How does it work with unit testing though? How do you unit test those functions, if cookies aren't available when running unit test with e.g. jest?

Mock them, i guess.

emilqva avatar Aug 14 '24 15:08 emilqva

Anyone knows if there is a solution for creating a global instance of the client yet?

emilqva avatar Aug 14 '24 15:08 emilqva

screenshot-2024-08-15-at-17 01 17

saltcod avatar Aug 15 '24 19:08 saltcod

What if you want to use unstable_cache which doesn't allow the client (using cookies) to be initialized inside the function?

emilqva avatar Aug 15 '24 19:08 emilqva

I found a workaround and thought maybe someone would appreciate it.

getCachedNotifications is just unstable_cache wrapped around the logic for getting the notifications. What is important is to not initialize supabase ssr client inside the cache function as the supabase ssr client uses cookies (user data) - which we don't want to cache.

export const getNotificationsAction = async ({
  archived = false,
}: {
  archived?: boolean
}) => {
  const supabase = createSupabaseServerClient()

  const { data, error } = await supabase.auth.getUser()

  if (error || !data.user) {
    throw new Error('You must be signed in to perform this action')
  }

  return getCachedNotifications(supabase, data.user.id, archived)
}

emilqva avatar Aug 16 '24 11:08 emilqva

I was having a similar issue, I was able to fix it by ensuring that my createClient() statements are within the functions of my code. For example, your actions.ts should be updated to the below:

Actions.ts

"use server"

import { createClient } from "@/utils/supabase/server";

export async function getLatestProjects() {
  const supabase = createClient();
    let { data: projects, error } = await supabase
  .from('new_projects')
  .select('*')
  .order('end_date', { ascending: false })
  .limit(10);

    if (error) throw error;

    return projects;
}

@robskinney Thanks, this solution worked. The problem was that when we initialise supabase client outside the scope of a function is that it doesn't have access to cookies cause cookies aren't available outside of an http request. Next.js collects static page data when building the project and since cookies are not available at build-time, it throws an error.

Make sure to only initialise this in a function or scope where it has access to cookies, otherwise this error would be thrown.

verbose117 avatar Aug 17 '24 06:08 verbose117

An error message appears:

Error: cookies was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context

Environment: Next.js 14 with Supabase.

To account for scalability, I'm using the Supabase client as shown below.

Service.ts

import { Database } from '@/types/supabase';
import { createSupabaseClient as createSupabaseClientUtil } from '@/utils/supabase/createClient';
import { SupabaseClient } from '@supabase/supabase-js';

// Differentiating between server or client based on runtime environment
abstract class Service {
  protected supabase: SupabaseClient<Database>;

  constructor() {
    this.supabase = createSupabaseClientUtil();
  }
}

export default Service;

utils/supabase/createClient.ts

import { createClient } from '@supabase/supabase-js';

export function createSupabaseClient() {
  const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
  const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;

  if (typeof window === 'undefined') {
    // eslint-disable-next-line @typescript-eslint/no-require-imports
    const { headers, cookies } = require('next/headers');
    return createClient(supabaseUrl, supabaseKey, {
      auth: {
        persistSession: false,
        detectSessionInUrl: false
      },
      global: {
        headers: {
          ...Object.fromEntries(headers().entries()),
          Cookie: cookies().toString()
        }
      }
    });
  } else {
    return createClient(supabaseUrl, supabaseKey);
  }
}

createClient.ts

import { createClient } from '@supabase/supabase-js';
import { createServerClient, type CookieOptions } from '@supabase/ssr';
import { Database } from '@/types/supabase';

export function createSupabaseClient() {
  const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
  const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;

  if (typeof window === 'undefined') {
    // eslint-disable-next-line @typescript-eslint/no-require-imports
    const { cookies } = require('next/headers');

    const cookieStore = cookies();

    return createServerClient<Database>(supabaseUrl, supabaseKey, {
      cookies: {
        get(name: string) {
          return cookieStore.get(name)?.value;
        },
        set(name: string, value: string, options: CookieOptions) {
          try {
            cookieStore.set({ name, value, ...options });
          } catch (error) {
            // Ignored if `set` is called from a Server Component.
          }
        },
        remove(name: string, options: CookieOptions) {
          try {
            cookieStore.set({ name, value: '', ...options });
          } catch (error) {
            // Ignored if `delete` is called from a Server Component.
          }
        }
      }
    });
  } else {
    return createClient<Database>(supabaseUrl, supabaseKey);
  }
}

I use it as follows:

AdminInstructor-service.ts

import Service from '@/service/Service';
import { MEMBERS_PER_PAGE } from '@/utils/constants';

class AdminInstructorService extends Service {
  // Retrieve all instructors
  public async all(pageParam: number) {
    if (pageParam > 1) {
      await new Promise(resolve => setTimeout(resolve, 500));
    }
    const start = (pageParam - 1) * MEMBERS_PER_PAGE;
    const end = start + MEMBERS_PER_PAGE - 1;

    const { data, count, error } = await this.supabase
      .from('instructors')
      .select('*', { count: 'exact' })
      .order('created_at', { ascending: false })
      .range(start, end);

    const totalPage = count ? Math.ceil(count / MEMBERS_PER_PAGE) : 0;

    if (error) throw error;

    return {
      instructors: data,
      page: pageParam,
      totalPage
    };
  }

  // Create a new instructor
  public async createInstructor({ memberId, username }: { memberId?: string; username: string }) {
    if (memberId) {
      this.isInstructor(memberId); // Checks if the user is already an instructor
    }

    const { data: instructorData, error: instructorError } = await this.supabase
      .from('instructors')
      .insert({ instructor_name: username })
      .select('id, instructor_name')
      .single();

    if (instructorError) throw instructorError;

    const instructorId = instructorData.id;

    // If only a new instructor is created, memberId will be missing, so this part is skipped.
    if (memberId) {
      const { error: updateError } = await this.supabase
        .from('members')
        .update({ instructor_id: instructorId })
        .eq('id', memberId);

      if (updateError) throw updateError;
    }
  }

  public async deleteInstructor({ instructorId }: { instructorId: string }) {
    const { error } = await this.supabase.from('instructors').delete().eq('id', instructorId);

    if (error) throw error;
  }

  // Checks if already an instructor
  public async isInstructor(memberId: string) {
    const { data: memberData, error: memberError } = await this.supabase
      .from('members')
      .select('id, username, instructor_id')
      .eq('id', memberId)
      .single();

    if (memberError || !memberData) {
      throw new Error('404');
    } else if (memberData.instructor_id) {
      throw new Error('409');
    }
  }
}

// eslint-disable-next-line import/no-anonymous-default-export
export default new AdminInstructorService();

When I use React Query hydration in a server component, I get an error. What could be the cause?

jungsikjeong avatar Nov 01 '24 05:11 jungsikjeong

hmm i am also getting the same error when using supabase/server.ts

import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'

export function createClient() {
  const cookieStore = cookies()

  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            cookieStore.set(name, value, options),
          )
        },
      },
    },
  )
}

It happens when i am making a stripe webhook call and want to save user's data in supabase, it is working fine it i directly use supabase

import { createClient } from '@supabase/supabase-js'


const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
)

Same here. When using supabase/server.ts from official doc, impossible to use generateStaticParams().

And working with createclient from @supabase/supabase-js works, but is it ok to work this way ?

Alban-i avatar Jan 03 '25 16:01 Alban-i

just wanted to share something else, might help someone

In my case the client was already being created within a function

import { env } from '@/env';
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export async function createClient() {
  const cookieStore = await cookies();

  return createServerClient(
    env.NEXT_PUBLIC_SUPABASE_URL,
    env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll();
        },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options),
            );
          } catch {
            // The `setAll` method was called from a Server Component.
            // This can be ignored if you have middleware refreshing
            // user sessions.
          }
        },
      },
    },
  );
}

pretty standard, got it from the tutorial at https://supabase.com/docs/guides/auth/server-side/nextjs

Now, in my page I had the following

'use client';

import { SignUpForm } from "@/app/sign-up/signup-form";

export default function SignUpPage() {
  return (
    <div className="flex min-h-screen items-center justify-center">
      <div className="w-full max-w-md p-8 space-y-4 bg-card rounded-lg shadow-lg">
        <SignUpForm />
      </div>
    </div>
  );
}

but it wouldn't work, got the error in the title

the key was removing the 'use client' directive

gaspardip avatar Jan 20 '25 06:01 gaspardip

Hey! Thanks for the tips :)

On Mon, Jan 20, 2025 at 7:27 AM Gaspar Dip @.***> wrote:

just wanted to share something else, might help someone else

In my case the client was already being created within a function

import { env } from '@/env';import { createServerClient } from @.***/ssr';import { cookies } from 'next/headers'; export async function createClient() { const cookieStore = await cookies();

return createServerClient( env.NEXT_PUBLIC_SUPABASE_URL, env.NEXT_PUBLIC_SUPABASE_ANON_KEY, { cookies: { getAll() { return cookieStore.getAll(); }, setAll(cookiesToSet) { try { cookiesToSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options), ); } catch { // The setAll method was called from a Server Component. // This can be ignored if you have middleware refreshing // user sessions. } }, }, }, );}

pretty standard, got it from the tutorial at https://supabase.com/docs/guides/auth/server-side/nextjs

Now, in my page I had the following

'use client'; import { SignUpForm } from "@/app/sign-up/signup-form"; export default function SignUpPage() { return ( <div className="flex min-h-screen items-center justify-center"> <div className="w-full max-w-md p-8 space-y-4 bg-card rounded-lg shadow-lg"> <SignUpForm /> );}

but it wouldn't work, got the error in the title

the key was removing the 'use client' directive

— Reply to this email directly, view it on GitHub https://github.com/vercel/next.js/issues/67191#issuecomment-2601470193, or unsubscribe https://github.com/notifications/unsubscribe-auth/A5LSZ76T3E2J3TFAIMNSU7L2LSJL7AVCNFSM6AAAAABJ4K3OYWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMMBRGQ3TAMJZGM . You are receiving this because you commented.Message ID: <vercel/next. @.***>

emilqva avatar Jan 20 '25 08:01 emilqva

It seems that this bug is still present. I'm using the exact same code than the with-supabase example and when i press the Sign out button, this bugs shows up and i'm unable to sign out from my account. https://github.com/vercel/next.js/tree/canary/examples/with-supabase All of my createClient() calls are inside functions...

BodaThomas avatar Jan 31 '25 10:01 BodaThomas

@BodaThomas , can you share some code? Maybe we will be able to figure out something

therobertos007 avatar Jan 31 '25 10:01 therobertos007

I had this same issue and wanted to share how I was able to resolve it in my project. I had multiple security headers being set in my project root middleware.ts. I found that Next.js server actions require certain inline scripts to function properly and that my middleware was restricting the functionality causing the cookies was called outside a request scope error.

I changed my middleware to this which fixed it on my end:

import { type NextRequest } from "next/server";
import { updateSession } from "@/utils/supabase/middleware";

export async function middleware(request: NextRequest) {
  const res = await updateSession(request);

  // Security headers
  const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
  const cspHeader = `
    default-src 'self';
    script-src 'self' 'nonce-${nonce}' 'strict-dynamic' 'unsafe-eval' 'unsafe-inline';
    style-src 'self' 'nonce-${nonce}' 'unsafe-inline';
    img-src 'self' blob: data:;
    font-src 'self';
    object-src 'none';
    base-uri 'self';
    form-action 'self';
    frame-ancestors 'none';
    block-all-mixed-content;
    upgrade-insecure-requests;
  `;

  res.headers.set(
    "Content-Security-Policy",
    cspHeader.replace(/\s{2,}/g, " ").trim()
  );
  res.headers.set("X-Frame-Options", "DENY");
  res.headers.set("X-Content-Type-Options", "nosniff");
  res.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
  res.headers.set(
    "Permissions-Policy",
    "camera=(), microphone=(), geolocation=()"
  );

  return res;
}

export const config = {
  matcher: [
    "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
  ],
};

My key change was adding 'unsafe-eval' and 'unsafe-inline' to script-src. Probably a different way to do this but this is what I found worked on my end.

cmershon2 avatar Feb 08 '25 15:02 cmershon2

It seems that this bug is still present. I'm using the exact same code than the with-supabase example and when i press the Sign out button, this bugs shows up and i'm unable to sign out from my account. https://github.com/vercel/next.js/tree/canary/examples/with-supabase All of my createClient() calls are inside functions...

Just like you, all my calls to the createClient function are inside a function, but the issue persist:

export const loginAction = async (formData: FormData) => {
    const supabase = await createClient()
    const email = formData.get('email') as string
    const password = formData.get('password') as string

    const { error } = await supabase.auth.signInWithPassword({
        email,
        password,
    })

    if (error) {
        console.error('Login error:', error.message)
        redirect(`/auth/login?error=${encodeURIComponent(error.message)}`)
    }

    return redirect('/')
}
"dependencies": {
    "@supabase/ssr": "^0.5.2",
    "@supabase/supabase-js": "^2.48.1",
    "next": "15.1.7",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },

EDIT: My custom matcher missed some static assets, triggering redirects to /auth/login. This led to a syntax error in the browser console and cookie errors outside the request scope on the server. The simpler matcher from the docs fixed both by correctly excluding assets.

ann0nip avatar Feb 26 '25 06:02 ann0nip