next.js: getServerSideProps cannot be serialized as JSON. Please only return JSON serializable data types
_Edit from @leerob: See updated answer: https://github.com/vercel/next.js/issues/11993#issuecomment-1504415523_
Bug report
Describe the bug
I’m returning a row set from MySQL (using the mysql2 library) in my getServerSideProps. Getting the following error:
SerializableError: Error serializing
.data[0]returned from
getServerSidePropsin "/reports/[report]/[start]/[end]". Reason:
object ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types.
But calling JSON.stringify(data)
works just fine.
If I do a JSON.parse(JSON.stringify(data))
it works just fine, but that seems very odd.
To Reproduce
- Execute a query using the
mysql2
library - Return the row set as a prop in
getServerSideProps
- Get Error.
Expected behavior
I expect the data to be serialized without an error since JSON.stringify()
works just fine.
Additional context
Appears others are having this problem: https://stackoverflow.com/questions/61188494/getserversideprops-and-mysql-rowdatapacket
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 61
- Comments: 32 (6 by maintainers)
Commits related to this issue
- Make the “undefined filtering trick” less visible Next.js insists on not having explicit undefineds in page data: https://github.com/vercel/next.js/issues/11993 So we filter them out (just leaving ... — committed to cesko-digital/app by zoul 2 years ago
- Make the “undefined filtering trick” less visible Next.js insists on not having explicit undefineds in page data: https://github.com/vercel/next.js/issues/11993 So we filter them out (just leaving ... — committed to cesko-digital/app by zoul 2 years ago
- Make the “undefined filtering trick” less visible Next.js insists on not having explicit undefineds in page data: https://github.com/vercel/next.js/issues/11993 So we filter them out (just leaving ... — committed to cesko-digital/app by zoul 2 years ago
- Improve Next.js JSON deserisation and Run object handling See this thread: https://github.com/vercel/next.js/issues/11993 — committed to KiwiKid/LocationOfInterestExplorer by KiwiKid 2 years ago
The main reasoning behind this limitation is that with
getInitialProps
we used to allow anything that can be stringified and that resulted in some really hard to track down UX bugs when hydrating client-side. Eg the hydration would fail because suddenly theDate
object you had server-side is a string client-side.We need to serialize the result of getStaticProps/getServerSideProps because it has to be sent to the browser to do hydration.
So we basically went with a strict checking mechanism (only runs in development) in order to prevent this from happening. We can potentially add an option to bypass in the future if there’s enough need for it 👍
@timneutkens I don’t get why this issue is closed. It seems quite a lot of people are still stumbling upon this and there is demand for a better solution. A warning in development mode seems to be sufficient to help users track down hydration errors and it wouldn’t require everyone to use hacks to serialize dates and such.
I have the exact same problem with mongoose. I thought it was because of the ObjectId format, but even if I “stringify” the _id property before it gets sent to getServerSideProps() I get the same error.
I’ve also had the idea to use JSON.parse(JSON.stringify(data)) and it works. But it’s a silly solution if you ask me…
Any news on the PR?
For people using mongoose, I solved it using the
.lean()
method to convert in a plain javascript object and removing the object Id from the query as it follows:Credit to this post in StackOverflow
@timneutkens We’re on the same page.
My proposal is to automatically handle serialization via
.toJSON
.I’ll open a PR for it, since code > words.
+1 for an option to bypass.
I’ve disabled all type casting in mysql2 but the objects returned are still of type
TextRow
even though they are just plain javascript objects consisting of nothing but primitives. I have to dorows.map(row => ({...row}))
to keep from triggering that error.Given that the primary use case of this feature is to fetch data from some data store and shove it into props, I think this will become quite a pain.
Even if it was just a warning and not a hard error it could still be helpful in development.
if anyone works with axios, the object returned from the api call is in data field, so if all the response of the axios is passed,
next
will alert that it’s not serializable and function isn’t allowed. my solution:Newbie here to NextJS. It seems strange, especially since querying directly from a PostgreSQL db (via Prisma) usually brings up
createdAt
andupdatedAt
and other date fields.For now, doing what @jeromemeichelbeck recommends by parsing results through a converter:
Hi Folks. I think this was a red herring. I’m using the mysql2 library and I did not realize that it is doing some magic conversions behind the scenes to convert dates and some other mysql types to native javascript objects that cannot be serialized without conversion. JSON.stingify() attempts to convert these automatically but it appears Next.JS is using a different serialization method that does not do this conversion.
Now that I know more about what’s going on I think the approach the Next.JS team is taking is the correct one. It’s better to be explicit and give the developer full control than to do magical conversions that may or may not be surprising. Maybe the Next.JS folks could add a “strict” configuration that allows people to opt in to the JSON.stringify() behavior?
For those of you still dealing with this you can continue with the
JSON.parse(JSON.stringify)
hack or you can make sure your data consists of easily-serializable primitives.I’m closing this issue now as it appears to be working as designed and is not a bug. If someone wants to open a feature request go for it.
I stumbled across a similar problem and got it working with by using the
superjson-next
plugin. See more here: https://github.com/blitz-js/superjson#using-with-nextjs@timneutkens @chrisbrantley I came across this recently while working on Next.js support for Amplify JS.
This throws an error (relevant code):
Whereas our
/api/posts
route works (due tores.json
):I understand the undesirable impact of using
JSON.stringify
, but would you be open to a PR that checked for.toJSON
as a final check/casting beforethrow
ing?https://github.com/zeit/next.js/blob/a4ab0887465d43ad3081e142924145a495b5727f/packages/next/lib/is-serializable-props.ts#L118-L132
Example: https://codesandbox.io/s/httpsgithubcomzeitnextjsissues11993-sumki?file=/pages/index.js:405-681
😐 After hours to think this ~ I fixed this 😃 Some data in query return is object like mongoID and it make JSON.parse not work. Yah I know I so nood.
This is solution https://github.com/blitz-js/superjson#using-with-nextjs
Superjson worked for me
Alright, check out https://github.com/zeit/next.js/pull/12156 👀
the _id and _v0 are object types. So according to MongoDB docs, we need to call a toString() method on these properties to get string values
i am getting data from firestore. faced the same issue because of timestamp in my response. i converted the result from firestore into a string with JSON.stringify() and then again from my props parsed it. working fine
In API routes it’s expected that you’re casting the values to JSON and they’re JSON client-side. With getStaticProps/getServerSideProps that is not the case and caused really tricky to debug hydration issues (we’ve seen these in production Next.js applications). As said I’m not opposed to adding an explicit option to bypass but the default behavior prevents production issues down the line.
Hopefully this helps someone struggling like me with the issue.
Mongo + Next:
_id
property name and other non-string propertyvalues
throw this errorDB method
Helper func to serialize data once it’s returned from the db method
I had the same issue today with objects returned from a
mysql2
query.This can be resolved without converting the result to json and back again by either using object assign or the spread operator.
So instead of
return myRetrievedObject;
, you can doreturn Object.assign({}, myRetrievedObject);
orreturn {...myRetrievedObject};
.Hope this helps!
if anyone here is getting this warning with mongo, you need to supress the _id field bc json does not support hex https://stackoverflow.com/a/52250461/1426788
@warcraft14115 I have a PR to fix it, but there were some rogue file-size tests that got it out of date.
I’ll have to get https://github.com/zeit/next.js/pull/12156 passing again and approved (I don’t think anyone has looked at it yet).
Update: while it makes sense that passing an
Object
(like aTimeslot
) would cause errors (because method’s can’t be serialized), I’ve implementedtoJSON()
andfromJSON()
methods that should make this work (but don’t):Still doesn’t work.
I’m having the same problem with a custom
Timeslot
object that’s pretty straight forward:Same as above,
JSON.stringify()
works just fine, but Next.js seems to be throwing the same error:Any suggestions?