Server Action is not ran / returns undefined, only on build.
Answered
Spinge Bib Sqorpnts posted this in #help-forum
Hello! In versions newer than 15.0.0-canary.120, not sure in which one specifically this begins to happen, but some server actions simply do not return any value.
for context, I have an async function inside a useEffect that runs on-mount, and calls a function that is in a file with
for context, I have an async function inside a useEffect that runs on-mount, and calls a function that is in a file with
use server
at the top. That function calls another server action, which is supposed to return a JSON object, and the first function returns the value of the second function. In that one particular place the second function does log the value it is supposed to return, but the second function doesn't log anything and the one inside the useEffect logs undefined
.Answered by Spinge Bib Sqorpnts
@joulev It seems I wasn't the only one experiencing this:
https://github.com/vercel/next.js/pull/69788
https://github.com/vercel/next.js/pull/69788
45 Replies
@Spinge Bib Sqorpnts Hello! In versions newer than 15.0.0-canary.120, not sure in which one specifically this begins to happen, but some server actions simply do not return any value.
for context, I have an async function inside a useEffect that runs on-mount, and calls a function that is in a file with `use server` at the top. That function calls another server action, which is supposed to return a JSON object, and the first function returns the value of the second function. In that one particular place the second function does log the value it is supposed to return, but the second function doesn't log anything and the one inside the useEffect logs `undefined`.
if it worked in 15.0.0-canary.x and doesn't work in 15.0.0-canary.x+1 then it's 100% a nextjs bug. could you find the specific release at which the bug appears?
server actions could return
undefined
if you change some headers in middleware though from your message i doubt it is the case@joulev if it worked in 15.0.0-canary.x and doesn't work in 15.0.0-canary.x+1 then it's 100% a nextjs bug. could you find the specific release at which the bug appears?
i'll try to pin-point it and I'll get back to you
@joulev server actions could return `undefined` if you change some headers in middleware though from your message i doubt it is the case
I haven't modified the middleware at all
@joulev it stops working on version 15.0.0-canary.126
.125 is the last version where it works correctly
Could it be this PR? https://github.com/vercel/next.js/pull/69178
@Spinge Bib Sqorpnts <@484037068239142956> it stops working on version 15.0.0-canary.126
yes this is 200% a nextjs bug. please file a bug report.
@joulev yes this is 200% a nextjs bug. please file a bug report.
See the thing is, opening an issue requires a repro link, and I have no idea why it happens in that specific place and I can't just upload the entire project
the above still logs 1 on the server and logs 2 on the browser as expected
the flow basically goes like this
// component
...
const [someState, setSomeState] = useState(/* some number */);
useEffect(() => {
const runFetch = async () => {
await action1()
}
}, [someState]);
// action1
'use server';
export async function action1() {
return await action2();
}
// action2
'use server'
export async function action2() {
return await fetch(/* */);
}
await action1()
returns undefined
in my casealso, it reproduces only on builds
it doesn't reproduce dev (turbo or without)
correction, the useEffect does have a dependency
Need to go out now, will check this later
@joulev Need to go out now, will check this later
sure, no problem
@Spinge Bib Sqorpnts the flow basically goes like this
tsx
// component
...
const [someState, setSomeState] = useState(/* some number */);
useEffect(() => {
const runFetch = async () => {
await action1()
}
}, [someState]);
tsx
// action1
'use server';
export async function action1() {
return await action2();
}
tsx
// action2
'use server'
export async function action2() {
return await fetch(/* */);
}
hhmm i can't reproduce though
"use server";
export async function action1() {
// If you do this, it doesn't work because Response is not a valid
// server action return value.
// return fetch("https://generate-secret.vercel.app/32");
// But you can do this just fine
const res = await fetch("https://generate-secret.vercel.app/32");
return res.text();
}
export async function action2() {
return action1();
}
could you make a minimal reproduction repository?
this is also exactly why all issues on github are required to have reproduction repositories, else they just read your issue and have no clue how that happened
@joulev this is also exactly why all issues on github are required to have reproduction repositories, else they just read your issue and have no clue how that happened
I'll try to reproduce it sometime tomorrow, I'm quite overworked for today
yup, take your time
@joulev this is also exactly why all issues on github are required to have reproduction repositories, else they just read your issue and have no clue how that happened
I'll start investigating now, but about this, while I get the idea, it becomes more difficult to treat edge-case problems in big projects that cannot be entirely reproduced due to it being for example, work property
okay I have a lead!
kind of at least
the code used to be
But when I changed it to:
It works!
// component
/* ... */
useEffect(() => {
async function GetData() { /* ... */ }
GetData();
}, [someState]);
But when I changed it to:
// component
/* ... */
async function GetData() { /* ... */ }
// Technically async callbacks are not allowed in useEffect 🤷♂️
// @ts-ignore
useEffect(GetData, [someState]);
It works!
I have no idea why, and I still think it's a bug, unless I broke a react rule by defining and calling a function inside a useEffect
wha- how is this even possible
I really don't know
@Spinge Bib Sqorpnts I'll start investigating now, but about this, while I get the idea, it becomes more difficult to treat edge-case problems in big projects that cannot be entirely reproduced due to it being for example, work property
you can use this method to make a minimal example:
* remove unrelated parts
* remove things bit by bit
* there will come a time when the bug goes away – the bit that makes the bug goes away is the critical bit
* remove unrelated parts
* remove things bit by bit
* there will come a time when the bug goes away – the bit that makes the bug goes away is the critical bit
i find it hard to make a minimal repro from a blank repo sometimes, but with this method though it takes more time and effort, it always works
I'll try to make something up
yeah certainly that's a huge lead, not enough to know what's wrong but enough to know it has something to do with useEffect
Imma try
useEffect(() => GetData())
Okay doing
useEffect(() => { GetData(); }, [someState]);
worksso I think it's about the Function Definition
I wonder if it's because some of the tree is dynamically imported?
nope
@joulev It seems I wasn't the only one experiencing this:
https://github.com/vercel/next.js/pull/69788
https://github.com/vercel/next.js/pull/69788
Answer
I tested out latest canary and it works now
nice to see, wow tricky bug