Infinite execution when using jotai-apollo atoms
hello 👋 , first of amazing library thank you so much. as I was using the lib I noticed that whenever I create an atom (from jotai-apollo) within a molecule it keeps infinitely running (maybe related to dependencies?)
Couple other things that I have tried:
- If i have a molecule that uses atoms from jotai-apollo, but I use it through an effect (jotai-effect) it works fine, and there is no infinite loading (see stackblitz)
- I tried to memoize the atom, the getter function (first param of
atomsWithQuery), I also tried to memoize the client getter (second param ofatomsWithQuery) but none of these worked. If I memoized the molecule constructor function then I got an error saying that the dependencies have changes which is not supported. - also if you move the jotai-apollo atom outside of the molecule it also works fine
here is a stackblitz with the issue: https://stackblitz.com/edit/vitejs-vite-xaz7lw?file=src%2FApp.tsx if you uncomment the following part:
{/* <ScopeProvider scope={TestScope}>
<InfiniteLoadingList />
</ScopeProvider> */}
you should see continuous console logs from the molecule:
if there is any way I can help please let me know (ex.: pr, tests etc...), although I'll probably require some assistance 🙏 .
Thanks for the reproduction @lazakrisz and the cases where it fails and where it doesn't. That's really helpful!
This sounds like a classic integration testing problem. jotai-apollo and bunshi may both be operating the right way, but not when paired together.

I don't know what may be causing this.
The biggest help you could do is to add some test cases to ScopeProvider.test.tsx. If you can make it fail, then open a draft PR with the failing tests, and I can help figure out how to make them pass.
The Void scopes can be used to create unique molecules test might be a good foundation. It uses createLifecycleUtils to make sure a molecule isn't created more times than needed, which we want to be 1 but in the case you've created is Infinite.
thank you @loganvolkers , will start to investigate this! 🔍
Update as I was investigating this:
- it seems the issue is related to Suspense boundaries and async atom data fetching behaviours and not references / memoization issues
by default each async atom in jotai uses Suspense in order to suspend until the data is available. (source: https://jotai.org/docs/utilities/async)
If the Suspense Boundary is wrapping the component that is suspending while the promise is pending (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L570) then all is good ✅ .
However if the Suspense boundary is wrapping the entire application (in my Apps case) or in case of this test (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L635) then the Suspense boundary is never unmounted (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L684).
Furthermore I have also forked and updated the Stackblitz to showcase this same behaviour: https://stackblitz.com/edit/vitejs-vite-eqmpey?file=src%2FApp.tsx
I have added the new code within the LoadableList.
I also want to mention that there are currently two solutions to this problem from an application perspective:
- use a Suspense boundary wrapping the component which is directly using the Promise atom (in my case and the Stackblitz's this is the atom that does the fetching using jotai-apollo)
- Use a loadable from jotai/utils as mentioned in the jotai docs in order to not use Suspense while the Promise is pending.
I believe both are valid solutions, let me know what you think @loganvolkers 👍