Skip to content

Fix breadcrumb infinite loop#18561

Merged
Weiko merged 1 commit intomainfrom
tt-fix-breadcrumb-infinite-loop
Mar 11, 2026
Merged

Fix breadcrumb infinite loop#18561
Weiko merged 1 commit intomainfrom
tt-fix-breadcrumb-infinite-loop

Conversation

@thomtrp
Copy link
Copy Markdown
Contributor

@thomtrp thomtrp commented Mar 11, 2026

RecordTableNoRecordGroupScrollToPreviousRecordEffect uses useAtomState(lastShowPageRecordIdState) to read the atom value and check whether to trigger an effect. Inside run(), it calls setLastShowPageRecordId(null) to reset the atom, then triggerInitialRecordTableDataLoad() which fires many store.set() calls on other atoms.

These high-frequency store updates cause the component to re-render before Jotai's internal useReducer dispatch (propagating the null value) is processed by React. The result: useAtomState returns a stale non-null value on every subsequent render, even though the Jotai store already holds null. The effect re-runs, sees the stale non-null value, calls run() again, creating an infinite loop.

This is a Jotai v2 edge case where useAtom's rendered value desyncs from the actual store value under high-frequency concurrent updates.

The fix

Read lastShowPageRecordId directly from the Jotai store via store.get() inside the effect instead of relying on the rendered value from useAtomState. This guarantees the effect always sees the true store value and correctly skips when the atom is null.

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

@thomtrp thomtrp added this pull request to the merge queue Mar 11, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 11, 2026
@thomtrp thomtrp added this pull request to the merge queue Mar 11, 2026
@thomtrp thomtrp removed this pull request from the merge queue due to a manual request Mar 11, 2026
@Weiko Weiko merged commit a024a04 into main Mar 11, 2026
81 checks passed
@Weiko Weiko deleted the tt-fix-breadcrumb-infinite-loop branch March 11, 2026 17:26
@twenty-eng-sync
Copy link
Copy Markdown

Hey @thomtrp! After you've done the QA of your Pull Request, you can mark it as done here. Thank you!

Devessier pushed a commit that referenced this pull request Mar 11, 2026
`RecordTableNoRecordGroupScrollToPreviousRecordEffect` uses
`useAtomState(lastShowPageRecordIdState)` to read the atom value and
check whether to trigger an effect. Inside `run()`, it calls
`setLastShowPageRecordId(null)` to reset the atom, then`
triggerInitialRecordTableDataLoad()` which fires many `store.set()`
calls on other atoms.

These high-frequency store updates cause the component to re-render
before Jotai's internal useReducer dispatch (propagating the null value)
is processed by React. The result: useAtomState returns a stale non-null
value on every subsequent render, even though the Jotai store already
holds null. The effect re-runs, sees the stale non-null value, calls
`run()` again, creating an infinite loop.

This is a Jotai v2 edge case where useAtom's rendered value desyncs from
the actual store value under high-frequency concurrent updates.

### The fix

Read lastShowPageRecordId directly from the Jotai store via
`store.get()` inside the effect instead of relying on the rendered value
from useAtomState. This guarantees the effect always sees the true store
value and correctly skips when the atom is null.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants