vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.88k stars 26.97k forks source link

Runtime Edge throws an "Invariant: Method expects to have requestAsyncStorage, none available" #52176

Closed NastykSwED closed 8 months ago

NastykSwED commented 1 year ago

Verify canary release

Provide environment information

Operating System:
      Platform: win32
      Arch: x64
      Version: Windows 10 Pro
    Binaries:
      Node: 18.16.0
      npm: N/A
      Yarn: N/A
      pnpm: N/A
    Relevant Packages:
      next: 13.4.8
      eslint-config-next: 13.4.8
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true), Metadata (metadata, generateMetadata, next/head, head.js), Middleware / Edge (API routes, runtime)

Link to the code that reproduces this issue or a replay of the bug

https://github.com/NastykSwED/next-edge-invariant-error

To Reproduce

  1. pnpm install

  2. pnpm dev

  3. Go to localhost:3000

  4. Look at terminal, see error:

    error Error: Invariant: Method expects to have requestAsyncStorage, none available
    at RootLayout (./src/app/layout.tsx:23:71)
    at stringify (<anonymous>)
    digest: "3964514174"

Describe the Bug

When using the runtime edge, if we use the headers() functions from "import { headers } from 'next/headers'", this error occurs, not only in layout.tsx | jsxfiles but also in page.tsx | jsx files and ingenerateMetadata functions. The error does not occur in older versions such as next@13.4.7: layout.tsx file Screenshot_1

page.tsx file Screenshot_2

generateMetadata function Screenshot_3

Expected Behavior

It would be expected that when using the runtime edge this error would not occur. In earlier versions such as next@13.4.7 it works correctly.

Which browser are you using? (if relevant)

Microsoft Edge 114.0.1823.67

How are you deploying your application? (if relevant)

HotCustard commented 1 year ago

Same deal with cookies() I noticed that when deployed to Vercel it runs fine, it only appears to be an issue on localhost.

balazsorban44 commented 1 year ago

@HotCustard do you have a reproduction? I tried running the one in the description, but I could not reproduce this. :thinking:

balazsorban44 commented 1 year ago

@NastykSwED the screenshots look different from the linked reproduction (page.tsx) could you update it so it is the same code?

github-actions[bot] commented 1 year ago

We cannot recreate the issue with the provided information. Please add a reproduction in order for us to be able to investigate.

Why was this issue marked with the please add a complete reproduction label?

To be able to investigate, we need access to a reproduction to identify what triggered the issue. We prefer a link to a public GitHub repository (template for pages, template for App Router), but you can also use these templates: CodeSandbox: pages or CodeSandbox: App Router.

To make sure the issue is resolved as quickly as possible, please make sure that the reproduction is as minimal as possible. This means that you should remove unnecessary code, files, and dependencies that do not contribute to the issue.

Please test your reproduction against the latest version of Next.js (next@canary) to make sure your issue has not already been fixed.

I added a link, why was it still marked?

Ensure the link is pointing to a codebase that is accessible (e.g. not a private repository). "example.com", "n/a", "will add later", etc. are not acceptable links -- we need to see a public codebase. See the above section for accepted links.

What happens if I don't provide a sufficient minimal reproduction?

Issues with the please add a complete reproduction label that receives no meaningful activity (e.g. new comments with a reproduction link) are automatically closed and locked after 30 days.

If your issue has not been resolved in that time and it has been closed/locked, please open a new issue with the required reproduction.

I did not open this issue, but it is relevant to me, what can I do to help?

Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps. Furthermore, you can upvote the issue using the :+1: reaction on the topmost comment (please do not comment "I have the same issue" without reproduction steps). Then, we can sort issues by votes to prioritize.

I think my reproduction is good enough, why aren't you looking into it quicker?

We look into every Next.js issue and constantly monitor open issues for new comments.

However, sometimes we might miss one or two due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.

Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.

Useful Resources

NastykSwED commented 1 year ago

@balazsorban44 Fixed!

walljalen commented 1 year ago

Is there a solution for this issue? I'm on Windows as well.

Update: I found that Next version 13.4.7 works and the issue has gone away. Also Windows users - on 13.4.8 and up the "@" import alias doesn't work in my experience.

BenBab commented 1 year ago

I am getting the same issue 'Invariant: Method expects to have requestAsyncStorage, none available' When using headers(). Happening in next 13.4.8 and 13.4.9

StockBet commented 1 year ago

Having the same issue. using cookies for supabase on server side api to receive a webhook.

import { cookies } from 'next/headers' import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'

const supabase = createServerComponentClient({ cookies })

Getting this error when deployed on vercel Error: Invariant: Method expects to have requestAsyncStorage, none available

joulev commented 1 year ago

@balazsorban44 The error can be reproduced by using cookies in middleware

import { cookies } from "next/headers";

export function middleware() {
  cookies();
}
next info output (macOS) Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 22.5.0: Thu Jun 8 22:21:34 PDT 2023; root:xnu-8796.121.3~7/RELEASE_ARM64_T8112 Binaries: Node: 20.3.1 npm: 9.6.7 Yarn: 1.22.19 pnpm: 8.6.5 Relevant Packages: next: 13.4.10-canary.0 eslint-config-next: N/A react: 18.2.0 react-dom: 18.2.0 typescript: 5.1.6 Next.js Config: output: N/A
next info output (Linux) Operating System: Platform: linux Arch: x64 Version: #48-Ubuntu SMP Tue Jun 20 20:34:08 UTC 2023 Binaries: Node: 18.16.0 npm: 9.5.1 Yarn: 1.22.19 pnpm: 8.6.6 Relevant Packages: next: 13.4.10-canary.0 eslint-config-next: N/A react: 18.2.0 react-dom: 18.2.0 typescript: 5.1.6 Next.js Config: output: N/A

Using cookies() in page.tsx files with runtime = "edge" works fine in both places in my case. So I think a significant portion of the reports on this issue is due to users using cookies() inside the middleware file (a user is also similarly confused in the Next.js Discord server).

If cookies() is not supposed to work in middleware I think it's necessary to provide a clearer error message than an invariant error like this one.

For other people encountering this issue with using cookies() in edge runtime page files (not middleware), maybe try to reproduce it in macOS or Linux, and see if it's still there? I don't have a Windows machine to test with me.

alrightsure commented 1 year ago

I'm getting this same issue now even on 13.4.7, but only when deployed. It works fine locally.

aabassiouni commented 1 year ago

I had this issue trying to run Clerk Auth on edge on the newest version (13.4.9). It seems to be only in windows environments. I tested the repo in WSL2 and I stopped getting the error. Windows will only work up til 13.4.7.

BenBab commented 1 year ago

I had this issue trying to run Clerk Auth on edge on the newest version (13.4.9). It seems to be only in windows environments. I tested the repo in WSL2 and I stopped getting the error. Windows will only work up til 13.4.7.

Yeah I was also having issues with both clerk Auth and also getting the Invariant: Method expects to have requestAsyncStorage when using headers() on a server components or middleware.

It only happens on my windows environment though.

Using wsl2 in dev it works okay on version 13.4.9

alexeygorbachevsky commented 1 year ago

Version 13.4.9, have same issue only locally (Windows), evrth is okay when deployed.

image

NastykSwED commented 1 year ago

The error still occurs in the latest version of next@13.4.11 on Windows OS.

AirmanEpic commented 1 year ago

Reproduced on 13.4.12 on Windows OS as well

Edit: in my case, it was because I was using cookies() in the pages router. OP is not so that's not his issue but if you encounter this issue like me with the pages router, my understanding is that of this version you need to create your own helper function to set cookies.

Again, only for the pages router. Pages router just means that your routes are in a directory like "pages/*" instead of app. Do not use cookies() if your api route with pages.

emrecoban commented 1 year ago

The issue was solved through this way: https://github.com/vercel/next.js/issues/45371#issuecomment-1655408690

The issue:

In prod, Next.js throws that error message: Invariant: Method expects to have requestAsyncStorage, none available. This error message occurs only server components and also in prod (Deploy on Cloudflare). No issue in local.

When it throws the error:

When it was fetching data from Supabase database in the server components in prod, not local.

Dependencies:

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

next-info:

    Operating System:
      Platform: linux
      Arch: x64
      Version: #50-Ubuntu SMP PREEMPT_DYNAMIC Mon Jul 10 18:24:29 UTC 2023
    Binaries:
      Node: 18.16.0
      npm: 9.5.1
      Yarn: 1.22.19
      pnpm: 8.6.7
    Relevant packages:
      next: 13.3.0
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0

Dashboard component:

import { createServerSupabaseClient, getSession } from "@/components/supabase/supabase-server";

export default async function Dashboard() {
    const supabase = createServerSupabaseClient() // this line works well.
    const serverSession = await getSession() // this line works well.
    const userInfo = serverSession?.user

    const pending = await supabase
        .from('table')
        .select('*', { count: 'exact', head: true })
        .eq('username', userInfo.user_metadata.username)
        .eq('status', 0)

    // Here's the error:
    console.log("ERROR [PENDING] DETAILS: ", JSON.stringify(pending, null, 2))
}

supabase-server.js:

import { cookies } from 'next/headers';
import { cache } from 'react';
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';

export const createServerSupabaseClient = cache(() =>
    createServerComponentClient({ cookies })
)

export async function getSession() {
    const supabase = createServerSupabaseClient()
    try {
        const {
            data: { session }
        } = await supabase.auth.getSession()
        return session
    } catch (error) {
        console.error('Error:', error)
        return null
    }
}

middleware.js:

import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'
import { NextResponse } from 'next/server'

export async function middleware(req) {
    const res = NextResponse.next()
    const supabase = createMiddlewareClient({ req, res })
    await supabase.auth.getSession()
    return res
}

Additional:

I guess the problem comes from the next/headers package. But why is it working in local? Everything is perfect in the client components, also in local. I don't want to do prop drilling.

A comment about this issue from GitHub: https://github.com/vercel/next.js/issues/45371#issuecomment-1652192961

oliver-oloughlin commented 1 year ago

I also ran into this issue on NextJS 13.4.12, also on windows. For me I encountered the issue when implementing Clerk authentication, specifically when using the ClerkProvider component. Fixed it by reverting to NextJS version 13.4.7.

NastykSwED commented 1 year ago

The error still occurs in version 13.4.13

Enalmada commented 1 year ago

Issue remains in version 13.4.14-canary.1. It is a windows only bug. It works fine in WSL.

reproduction: on Windows, access cookies() on a page with runtime edge

import { cookies } from "next/headers";

export const runtime = "edge";

export default function Page() {
  const cookieStore = cookies();
  return null;
}
image

reproduction where I am actually trying to get this to work: https://github.com/awinogrodzki/next-firebase-auth-edge/issues/80

npx next info

    Operating System:
      Platform: win32
      Arch: x64
      Version: Windows 10 Pro
    Binaries:
      Node: 18.16.0
      npm: N/A
      Yarn: N/A
      pnpm: N/A
    Relevant Packages:
      next: 13.4.14-canary.1
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

@balazsorban44 could this reproduction be enough to get this fixed?

EliotCampbell commented 1 year ago

Same problem im middleware.js on windows locally

"next": "^13.4.13",

if (request.method !== 'OPTIONS') { const token = getCookies() console.log(token) return NextResponse.next() }

NastykSwED commented 1 year ago

The error still occurs in version 13.4.15 and 13.4.15-canary.0

christophmeise commented 1 year ago

Still facing the error on Windows 11 in version 13.4.16

NastykSwED commented 1 year ago

The error still occurs in version 13.4.19 and 13.4.20-canary.15

NastykSwED commented 1 year ago

The error still occurs in version 13.4.20-canary.40

oliver-oloughlin commented 1 year ago

Error still persists on version 13.5.2. I'm on windows and have tried running it normally and using WSL.

oliver-oloughlin commented 1 year ago

Error also persists in version v13.5.3-canary.0

blackpill commented 1 year ago

Error also persists in version v13.5.3 The bug only occurs on windows. The same code can run correctly on MacOS and vercel.

anuraagvaidya commented 1 year ago

Same error for me. Has a fix been identified?

Node version = v18.12.1 Package version: next@13.5.4-canary.11 OS: Windows 11

Use case:

import { cookies } from 'next/headers'
export async function GET(request) {
  const requestUrl = new URL(request.url)
  const code = requestUrl.searchParams.get('code')

  if (code) {
    const supabase = createRouteHandlerClient({ cookies })
    await supabase.auth.exchangeCodeForSession(code)
  }
//irrelevant code
}
w3nder commented 1 year ago

I downgraded next to 13.5.3 and it works. Node 18 Windows 11

oliver-oloughlin commented 1 year ago

Tried Next 13.5.3 with Node 18 on Windows 11, still no luck for me. Latest version that works is 13.4.7

christophmeise commented 1 year ago

I am still facing the same issue with Next 13.5.5-canary.4 with Node 18 and Windows 11. The same code is working fine on MacOS.

With this bug, I can not declare any page as runtime edge for local development when working on Windows.

anuraagvaidya commented 1 year ago

I can confirm that @oliver-oloughlin's solution is right. It worked for me as well on 13.4.7. Obviously, --experimental-https flag wasn't supported on 13.4.7, so I ended up using local-ssl-proxy as described in this issue

benjick commented 1 year ago

I'm getting this error running bun test, bun version 1.0.4, next version 13.5.4

w3nder commented 1 year ago

"next": "13.5.5-canary.14",also solves the problem

benjick commented 1 year ago

@w3nder thank you, but it's not working for me, still failing with bun test

"version": "13.5.5-canary.14",

christophmeise commented 1 year ago

Also still broken for me, tested with 13.5.5-canary.17

"next": "13.5.5-canary.14",also solves the problem

heblol commented 1 year ago

I got the same error and I got it working somehow. I tried many things, but these were my last two steps.

I did:

  1. Downgraded to "next:" 13.4.7
  2. Added "use server" to the component that called cookies and also made it a async function (which was required for the "use server" flag).
"use server"; // added "use server"
// This only works server-side!
import { Database } from "@/types/supabase";
import { createServerActionClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";

async function supabaseServerSide() { //Made an async export function
  const cookiesStore = cookies();

  const supabase = createServerActionClient<Database>({
    cookies: () => cookiesStore,
  });

  return supabase;
}

export default supabaseServerSide;

Now calling the supabase server function like this in my React component. It looks a bit ugly because of the await (await ..)

import NavLink from "@/components/NavLink";
import supabaseServerSide from "@/components/server/supabase/supabase";
import { Card, Col } from "antd";

import { PropsWithChildren } from "react";

export default async function AuthenticatedLayout(props: PropsWithChildren) {

  const { data: currentUser, error } = await (await supabaseServerSide())
    .schema("public")
    .from("user_profile")
    .select("*");

  if (!session) {
    return (
      <Col
        xs={{
          span: 24,
        }}
        lg={{
          span: 16,
          offset: 4,
        }}
      >
        <Card title="You are not authenticated. Login first.">
          <NavLink href="/login">Go to login page</NavLink>
        </Card>
      </Col>
    );
  }

  return <div>{props.children}</div>;
}

I hope this works for others as well

azeemasim01 commented 12 months ago

This is more a platform related issue. So the localhost at windows machine was having this issue. I was able to resolve it by adding this line in app/page.js file

export const runtime = 'nodejs';

oliver-oloughlin commented 12 months ago

@azeemasim01 Yeah, but that's exactly the issue, runtime edge on windows causes the bug. I am using the edge runtime, so switching to nodejs is not a solution for me or anyone committed to edge.

joachimjusth commented 11 months ago

I'm also facing this issue. But more specificly.

The error only occured on dynamic route (app router).

Example:

Works perfectly:

// apps/dashboard/page.tsx

export default async function Dashboard() {
  const data = await api.myApiRoute.myProcedure();
  return <>Dashpage</>
}

On dynamic route, it throws the error Error: Invariant: headers() expects to have requestAsyncStorage, none available.

// apps/dashboard/posts/[postId]/page.tsx

type Props = {
  readonly params: {
    readonly postId: string;
  }
}

export default async function PostDetail({params: { postId }}: Props) {
  const data = await api.myApiRoute.myProcedure();
  return <>PostDetail page {postId}</>
}

the api is a simple trpc caller:

import "server-only";

import { headers } from "next/headers";
import { appRouter } from "~/server/api/root";
import { db } from "~/server/db";
import { auth } from "@clerk/nextjs";

export const api = appRouter.createCaller({
  db,
  headers: headers(), // here the error is throw
  auth: auth(),
});

there is my next info output:

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP Thu Oct 5 21:02:42 UTC 2023
Binaries:
  Node: 21.2.0
  npm: 10.2.3
  Yarn: N/A
  pnpm: 8.9.0
Relevant Packages:
  next: 13.5.6
  eslint-config-next: 13.5.6
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.2
Next.js Config:
  output: N/A

I'm working with clerk for the auth part.

What I found until now:

The return new maybeGlobalAsyncLocalStorage(); seems different regarding a request where it's ok. the value of the return:

AsyncLocalStorage {
  kResourceStore: Symbol(kResourceStore),
  enabled: false,
  _onPropagate: null
}

comparing to an ok:

AsyncLocalStorage {
  kResourceStore: Symbol(kResourceStore),
  enabled: true,
  _onPropagate: null
}

so it seems that the AsyncLocalStorage is disabled I was going deeper when I found out this type definition (from node):

        /**
         * Returns the current store.
         * If called outside of an asynchronous context initialized by
         * calling `asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()`, it
         * returns `undefined`.
         * @since v13.10.0, v12.17.0
         */
        getStore(): T | undefined;

I prepared a little repository to replicate the issue: https://github.com/joachimjusth/nextjs-issue-52176

I hope it'll help

nickverstocken commented 9 months ago

I have the exact same issue with Next 14.0.4 where a catch all route that only returns a "NotFound" page causes the issue... The application is completely server side renderen (except a few client side components). The issue only happen when I try to access draftMode which is related to headers as discussed here.

I am still looking for a workaround because it is annoying because I use a headless CMS and this is the entry point for editors to see their changes that are not approved an published yet

balazsorban44 commented 8 months ago

We've added a lot of improvements since this issue was opened, cookies() and headers() are supported in more places (for example Middleware, but also cannot reproduce issues with pages marked with export const runtime = "edge").

It looks like that comments have somewhat deviated from the original report, (which I verified working fine on next@canary) or did not add a reproduction. (we cannot investigate "same issue" comments).

In most cases, the issue is that you are calling headers() or cookies() outside the request context, so the error would be expected. I recently made a docs improvement that explains this with a better error message: https://github.com/vercel/next.js/pull/62143. See the rendered error explanation (and how to fix it) here: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context

Please upgrade, and if you are still having issues, open a new bug report with a minimal reproduction, thanks! :pray: (Note, a minimal reproduction means you don't assume the maintainer to register for third-party services, setting up env. secrets etc., unless it's really necessary to reproduce the bug.)