Bug: Server functions report false positive errors for MobX observables
Server functions will falsely report an error in development when called with a MobX observable, but the value is (usually) correctly serialized.
As far as I can tell, this is because MobX observables are Proxies, and either add .toJSON() methods to wrapped values which return different values in JSON.stringify() than the "original value", or they add a special Symbol(mobx administration) to objects which are skipped over in serialization.
I created an issue in the React repo as well in case they are able to tweak the heuristic for these errors.
Intended outcome:
Ideally, observable values would be serializable without error in React server functions.
This came up in a real scenario when I tried invoking a server function in a Next.js codebase and passing data which happened to be a Proxy created by MobX. Because proxy values are meant to be indistinguishable, there was also no TypeScript warning that this error would occur.
Actual outcome:
In development, calling a server function with a MobX observable value will cause the function to report a confusing error, but not fail.
How to reproduce the issue:
https://codesandbox.io/p/devbox/2w4qqc
To avoid this issue, I recommend to "serialize" the observables manually at this point, e.g. convert them back to plain objects. Several options are outlined here: https://mobx.js.org/observable-state.html#converting-observables-back-to-vanilla-javascript-collections
Conceptually it makes sense that this errors in React, as the observables contain internal state about which React can't reason that it doesn't matter if this doesn't get serialized. And note that not showing a warning, would lead to bug reports as well, along the lines of "I passed an observable to a server function and suddenly it is not observable on the server anymore".
Most ideally there would be some symbol (similar to toJSON) that allows us to customize how to convert back to plain value, which would then be picked up by MobX, making this all transparent to the developer.