mobx icon indicating copy to clipboard operation
mobx copied to clipboard

Bug: Server functions report false positive errors for MobX observables

Open denk0403 opened this issue 8 months ago • 1 comments

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.

Image

How to reproduce the issue:

https://codesandbox.io/p/devbox/2w4qqc

denk0403 avatar Jun 15 '25 01:06 denk0403

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.

mweststrate avatar Jun 15 '25 19:06 mweststrate