Repository navigation
fix(signals): a write recovers an errored writable memo without a torn read (#4110) - #4167
Conversation
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.
…its (#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
🦋 Changeset detectedLatest commit: bdc5d4f The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 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 |
Size (brotli, eager entry chunk)
|
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
Coverage Report for CI Build 39369656537Coverage remained the same at 77.555%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Merging this PR will improve performance by 11.9%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ⚡ | build + consume |
777 µs | 694.3 µs | +11.9% |
Tip
Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.
Comparing fix/writable-memo-error-4110 (cf4e5c8) with next (7014aca)
Footnotes
-
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. ↩
Summary
Fixes #4110. Supersedes #4143, whose commit by @Neekoras is kept here as-is; the second commit adds the changes from our review.
Before: a writable memo whose derivation threw kept throwing that error after
setValue(...). Effects stayed on their error arm and<Errored>never recovered. With #4143 alone the memo recovered, but a read between the write and its flush (or under an action holding the write) returned the old value instead of the error, a torn read.After: a write to an errored writable memo recovers it when the write commits. Until then the error stays what readers see (D-41), so a read before the flush, or an untracked read mid-action, still throws. A write made after a pass staged an error under the same action now lands as a value. Before this, effects received the written value on their error arm, a case left over from #4148.
How: in
setMemo, an errored node records its error as the shown error beforesetSignal, then clearsSTATUS_ERROR. The shown error also lets a write equal to the last good value through the equality gate. AftersetSignal, the write clearsCONFIG_STAGED_ERROR, because the staging is now a value.Size: about +50 B minified on the core floor (+60 B including #4163, which merged without re-recording). Hello world (
app: compiled floor) stays under 10 KB brotli at about 9.88 KB. Caps will be raised from this PR's CI numbers with dated ledger notes.Size-Exception: a write must recover an errored writable memo without a torn read (#4110); the maintainer accepted about +50 B on the core floor on 2026-10-20.
How did you test this change?
packages/signals/tests/writable-memo-write-clears-error-4110.test.tskeeps fix(signals): a write clears a writable memo's previous error #4143's two tests and adds four: a read before the write's flush still throws, a write held by an action shows the error until it commits,<Errored>recovers when the action's write commits, and a write after a staged error in the same action lands as a value. Three of the new tests fail with fix(signals): a write clears a writable memo's previous error #4143's commit alone, and all six pass with this PR.Generated by Claude Code