-
Notifications
You must be signed in to change notification settings - Fork 27k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
14.1.1 version introducing breaking change for cookies() #62727
Comments
This appears very similar to an issue I found with 14.1.1. It's not cookies or headers, but I'm using I confirmed the issue occurs with 14.1.2-canary.1 |
For my issue I discovered by having |
hey thanks for reporting, we're hoping to fix the issue today or tomorrow! we will trigger a patch then |
Hey everyone! It turned out to be a bug that previously it's allowed to mark synchronous functions with |
As mentioned in the new-added error messages, and the [linked resources](https://react.dev/reference/react/use-server#:~:text=Because%20the%20underlying%20network%20calls%20are%20always%20asynchronous%2C%20%27use%20server%27%20can%20only%20be%20used%20on%20async%20functions.): > Because the underlying network calls are always asynchronous, 'use server' can only be used on async functions. > https://react.dev/reference/react/use-server It's a requirement that only async functions are allowed to be exported and annotated with `'use server'`. Currently, we already have compiler check so this will already error: ```js 'use server' export function foo () {} // missing async ``` However, since exported values can be very dynamic the compiler can't catch all mistakes like that. We also have a runtime check for all exports in a `'use server'` function, but it only covers `typeof value === 'function'`. This PR adds a stricter check for "use server" annotated values to also make sure they're async functions (`value.constructor.name === 'AsyncFunction'`). That said, there are still cases like synchronously returning a promise to make a function "async", but it's still very different by definition. For example: ```js const f = async () => { throw 1; return 1 } const g = () => { throw 1; return Promise.resolve(1) } ``` Where `g()` can be synchronously caught (`try { g() } catch {}`) but `f()` can't even if they have the same types. If we allow `g` to be a Server Action, this behavior is no longer always true but depending on where it's called (server or client). Closes #62727.
As mentioned in the new-added error messages, and the [linked resources](https://react.dev/reference/react/use-server#:~:text=Because%20the%20underlying%20network%20calls%20are%20always%20asynchronous%2C%20%27use%20server%27%20can%20only%20be%20used%20on%20async%20functions.): > Because the underlying network calls are always asynchronous, 'use server' can only be used on async functions. > https://react.dev/reference/react/use-server It's a requirement that only async functions are allowed to be exported and annotated with `'use server'`. Currently, we already have compiler check so this will already error: ```js 'use server' export function foo () {} // missing async ``` However, since exported values can be very dynamic the compiler can't catch all mistakes like that. We also have a runtime check for all exports in a `'use server'` function, but it only covers `typeof value === 'function'`. This PR adds a stricter check for "use server" annotated values to also make sure they're async functions (`value.constructor.name === 'AsyncFunction'`). That said, there are still cases like synchronously returning a promise to make a function "async", but it's still very different by definition. For example: ```js const f = async () => { throw 1; return 1 } const g = () => { throw 1; return Promise.resolve(1) } ``` Where `g()` can be synchronously caught (`try { g() } catch {}`) but `f()` can't even if they have the same types. If we allow `g` to be a Server Action, this behavior is no longer always true but depending on where it's called (server or client). Closes #62727.
so, every function now which is in "use server" file must be asynchronous For mine use case, I was just using "use server" to mark exported function to just force run it on the server, which I am not sure now if that is really the thing I am now thinking if |
Yes @alimek, |
cool, thanks for clarification 👍 |
I have the below function which is used to get the cookie value, but now it gets a Promise. It broke my application. 'use server'
import { cookies } from 'next/headers'
// Definition:
export const getCookie = (name: string) => cookies().get(name)?.value
// Usage:
const myCookie = getCookie('myCookie') How do I best fix this right now? I recently moved from Next version // Definition: no change (❌ see my next comment for updated solution)
// Usage:
const myCookie = await getCookie('myCookie') This got it working again. TypeScript warns though: 'await' has no effect on the type of this expression. ts(80007) The question is: Will it break in a future release? Non-Promise values should fall through |
@ADTC assuming you had same problem like me, If you want to force your function be only available on server, change |
After a bit more reading, I seem to gather that all functions in a file that starts with And this is a permanent expectation of Server Actions that won't be reverted in a future release of Next.js. Is that right? In that case, I infer that the best fix is to also change the definition to make it // Definition:
export const getCookie = async (name: string) => cookies().get(name)?.value
// Usage:
const myCookie = await getCookie('myCookie') @alimek (You commented after I wrote the above already.) In my case, I cannot make your suggested change because I'm using these methods in client components as Server Actions. But yes, that's another possible solution if your methods are meant for server use only. |
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Link to the code that reproduces this issue
https://github.com/alimek/next-bug
To Reproduce
when calling getLanguage() or getToken() it should return always string, after upgrade to 14.1.1 its Promise
Current vs. Expected behavior
Current
generating
instead
Provide environment information
Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 Binaries: Node: 18.19.0 npm: 10.2.3 Yarn: 4.1.0 pnpm: 8.7.0 Relevant Packages: next: 14.1.1 eslint-config-next: 14.1.0 react: 18.2.0 react-dom: 18.2.0 typescript: 5.3.3 Next.js Config: output: standalone
Which area(s) are affected? (Select all that apply)
Not sure
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local)
Additional context
No response
NEXT-2660
The text was updated successfully, but these errors were encountered: