Skip to content

fix(signals): a write clears a writable memo's previous error - #4143

Closed
Neekoras wants to merge 2 commits into
solidjs:nextfrom
Neekoras:fix-4110-write-clears-memo-error
Closed

Neekoras wants to merge 2 commits into
solidjs:nextfrom
Neekoras:fix-4110-write-clears-memo-error

Conversation

@Neekoras

@Neekoras Neekoras commented Oct 19, 2026 •

Copy link
Copy Markdown

Fixes #4110. Superseded by #4167, which carried the original commit from this PR with contributor credit and added the maintainer's review fixes. #4167 is merged into next.

This PR originally proposed clearing a writable memo's error on a manual write, including when the replacement equals its last good value. The review identified a torn read before commit and a held staged-error case; both were addressed in #4167. The original tests are included there.

The fork branch received additional experimental changes after this PR was closed. Those changes were not part of #4167 or its review; #4167 is the authoritative merged fix.

STATUS_ERROR was only cleared by a recompute or an async settle, neither of which a direct write performs, so an errored memo kept throwing the stale error to every later reader.
@changeset-bot

changeset-bot Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e3abb80

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@solidjs/signals Patch
test-integration Patch
@solidjs/web Patch
@solidjs/babel-plugin Patch
@solidjs/compiler Patch
@solidjs/diagnostics Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/html Patch
solid-js Patch
@solidjs/universal Patch
board-example Patch
server-dbmon-example Patch
todos-server-example Patch

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

Copy link
Copy Markdown
Member

Thanks! After commit this works well. The effect, <Errored>, downstream memos and async-errored memos all recover, and a later dependency change re-throws or recovers correctly. One problem with the timing, though:

Torn read before commit. notifyStatus(el, STATUS_NONE) clears the error at write time, but the written value is only staged. So a read before flush() returns the last good value from before the error:

// memo had value 1, then failed; value() throws "boom"
setValue(2);
value(); // PR: 1 (stale). next: throws boom. Expected: boom (or 2), never 1

The same happens inside an action: after setValue(3); yield hold, an untracked read mid-transaction returns 1 (or undefined if the memo never had a good value). A suggestion: keep the error visible as _shownError at write time and drop STATUS_ERROR in commitPendingNode, which already clears _shownError on commit.

Size: +21–22 B minified per client scenario fails the Size gate on six scenarios, including signals: core floor (+29 B over its recorded size, so 9 B past the 20 B allowance) and app: compiled floor. Please trim, or add a Size-Exception: line to the PR body with the reason.

Also note #4148 fixes a sibling bug in the same area (CONFIG_STAGED_ERROR surviving when a value is staged over a held error). setMemo here clears STATUS_ERROR but not that flag, so a write inside an action over a held error still throws the value with both PRs merged. It's worth coordinating the two.

— Claude via Claude Code


Generated by Claude Code

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 39312359126

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage remained the same at 77.555%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1347
Covered Lines: 1103
Line Coverage: 81.89%
Relevant Branches: 1050
Covered Branches: 756
Branch Coverage: 72.0%
Branches in Coverage %: Yes
Coverage Strength: 27.42 hits per line

💛 - Coveralls

@codspeed

codspeed Bot commented Oct 19, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 10.63%

⚠️ 4 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 195 untouched benchmarks
⏩ 5 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ ⚠️ build + consume 693.8 µs 776.3 µs -10.63%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing Neekoras:fix-4110-write-clears-memo-error (e3abb80) with next (3cffd86)

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

Copy link
Copy Markdown
Member

Thank you for this fix. I've carried your commit unchanged into #4167, with authorship kept, and added the review changes on top: the error stays shown until the write commits, so there's no torn read, and a write clears a staged error. Your fork couldn't take pushes from us, which is why it's a separate PR. I'll close this one once #4167 merges.

— Claude via Claude Code


Generated by Claude Code

ryansolid added a commit that referenced this pull request Oct 20, 2026
…n read (#4110) (#4167)

* fix(signals): a write clears a writable memo's previous error

STATUS_ERROR was only cleared by a recompute or an async settle, neither of which a direct write performs, so an errored memo kept throwing the stale error to every later reader.

* fix(signals): keep a writable memo's error shown until the write commits (#4110)

Builds on #4143. The error stays the display until the write commits, so a
read between the write and its flush, or under the action holding it, still
throws instead of returning the old value. A write also clears an error a
pass staged under the same hold, so effects see the written value instead
of their error arm (the action-write case left from #4148).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LY7F9czoRqdMEvk2QwPr1

* chore(size): raise caps for the #4110 writable-memo error fix

Accepted by the maintainer on 2026-10-20: about +50 B minified on the core
floor. Also re-records #4163's +9 B, which merged without a re-record.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LY7F9czoRqdMEvk2QwPr1

---------

Co-authored-by: Nicholas <nickylin211@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>

Copy link
Copy Markdown
Member

#4167 is merged to next with your commit in it, and you're credited as co-author on the squash commit. Closing this one. Thanks again!

— Claude via Claude Code


Generated by Claude Code

@ryansolid ryansolid closed this Oct 20, 2026
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