immerjs / immer

Create the next immutable state by mutating the current one

Home Page:https://immerjs.github.io/immer/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"Maximum call stack exceeded" with circular references

joshkel opened this issue · comments

🐛 Bug Report

Starting with Immer 10.0.4, if Immer is given an object that uses symbols for circular references, it generates a "Maximum call stack exceeded" error.

Link to repro

https://playcode.io/1794809

To Reproduce

Pass an object with pre-existing symbol circular references to Immer 10.0.4. (Circular references that are added within an Immer recipe do not cause problems.)

Observed behavior

"Maximum call stack exceeded"

Expected behavior

Our application uses symbols to create child-to-parent relationships. Since symbols are skipped by many JavaScript routines (e.g., JSON.stringify, Immer prior to 10.0.4), we had been able to do this without error.

Environment

  • Immer version: 10.0.4
  • I filed this report against the latest version of Immer

Argh, the JS world is impossible. 50% is like "non-enumerables and proxies have very specific meanings", and the other half is like "I expect non-enumerables and symbol to work just like the rest, why treat them irregularly" 🤣

Would you mind trying setting the setUseStrictShallowCopy(false) flag? Maybe in combination with version 10.0.4-beta?

@mweststrate I get it. I apologize for contributing to your pain as an open-source maintainer.

setUseStrictShallowCopy(false) with 10.0.4 or 10.0.4-beta seems to have no effect.

For what it's worth, Immer 9.x's behavior seemed consistent and worked for my purposes:

  • Preexisting symbol props are skipped by Immer, as consistent with Object.values, JSON.stringify, etc. (I.e., this issue.)
  • If I add/set a symbol prop within Immer, it handles it well enough to avoid leaking proxies. (I.e., #1087.)

Hopefully that's too ad hoc / too much of a special case - but, if you decide it is, I understand.

Another way to reproduce this is trying to modify an object that contains React context: https://codesandbox.io/p/devbox/festive-gagarin-9mkfx9

For what it’s worth, the repro seems to work using immer@6.0.9

Yeah I guess the only way to deal with this is to make all the behavior of irregular properties of any kind (enumerable x getter x proxy) all configurable. That will be a a bit bigger project though so probably more for a next major.