fix(signals): keep a mainline effect value out of its parked transaction (#3412) - #3420
Merged
ryansolid merged 2 commits intoSep 14, 2026
Merged
Conversation
…ion (solidjs#3412) An effect stamped by a held transaction that recomputes on an unrelated write, and no longer reads the held source, publishes its value mainline. The forced re-run inside its own transaction (which only refreshes the staged view) re-stamped `_valueTransition`, so when finalization re-entered the transaction — a Loading `on` reset writing its `_disabled` signal — the effect phase parked the mainline value with it. Restore the owner after the re-run. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: b28a7ea The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
…p save/restore (+8 B) Co-authored-by: Cursor <cursoragent@cursor.com>
ryansolid
added a commit
to brenelz/solid
that referenced
this pull request
Sep 14, 2026
Resolve recompute's tail against solidjs#3420 (solidjs#3412): keep the held-children bookkeeping and the _valueTransition save/restore around the forced in-transaction re-run. Size ledger notes merged; caps unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3412
Problem
With a
Loading on={count()}boundary and an unconditionaldetails()reader outside it, flippingshowto false whiledetailsis still pending leavesshow() ? details() : "hidden"displaying the old value until the unrelated async settles.Cause
The count write opens a transaction that stays parked (Details and Panel read
details()outside any boundary), and both effects are stamped with it. On the later ambientshowwrite, Panel recomputes mainline, readsshowas false, and publishes"hidden"into_valuewith mainline ownership — which is what the flush's "everything computed mainline applies now" rule expects.recomputethen forces a second run of the effect inside its own parked transaction to refresh the staged view. That re-run only writes_pendingValue, but it also re-stamped_valueTransitionto the parked transaction, claiming ownership of the value the mainline run produced.During finalization the boundary sweep sees
copysettled and writes_disabled = false. That signal is stamped with the parked transaction (itsonreset staged the fallback flip there), so the write legitimately re-enters it mid-flush. With the transaction active and Panel's ownership pointing at it, therunEffectownership gate leaves Panel queued and the next pass parks it.Showapplies because it was never stamped.Without
on, nothing re-enters the transaction in that flush, so the misattributed ownership is harmless and Panel applies by accident — which is why the minimization looks like a boundary bug.Fix
Save
_valueTransitionbefore the forced in-transaction re-run and restore it afterward. The contested-effect bookkeeping is untouched, so the transaction still re-derives the effect against its own committed world at commit.Tests
packages/signals/tests/effect-mainline-ownership-3412.test.ts— the four-variant matrix (boundary /on/ unconditional reader) at the signals level; only the reporter's shape failed before the fix.packages/web/test/loading-on-outside-reader-3412.spec.tsx— the same matrix rendered through@solidjs/web.🤖 Generated with Claude Code