Repository navigation
Conversation
… reveal A memo that throws while an async sibling holds the frame stages its error (D-41): _pendingValue carries it and CONFIG_STAGED_ERROR marks it. A successful pass in the same hold replaced the staging with its value but left the flag set, so readers at the reveal threw the value as an error and halted the reactive system. The pass that stages a value now clears the flag. Fixes solidjs#4145
🦋 Changeset detectedLatest commit: bda2ad6 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 |
Merging this PR will degrade performance by 10.57%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ |
build + consume |
694.8 µs | 776.9 µs | -10.57% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing drakeo338:fix/held-error-recovery (bda2ad6) with next (fda29a4)
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. ↩
Generated by Claude Code |
CONFIG_STAGED_ERROR was cleared only at the commit. With a pass's own throw now staged whenever a flush runs, a memo that throws and re-runs in the same flush kept the flag: a value re-run was thrown as an error (its raw value reached the error arm, #4145), and a pending re-run left the superseded error to be published at the commit. A pass now drops an error staged by an earlier pass before it runs: its own answer (a value, a flight, or an error it stages again) replaces it. This folds in #4148's clear on the value path. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
…4109) (#4156) * fix(signals): stage a pass's error before the flush joins its hold (#4109) A synchronous memo whose pass threw in a flush published the error at once unless the flush had already joined a hold. When the pass ran before its async sibling went pending, the error showed ahead of the frame (D-41): an untracked read threw while the screen still showed the committed value. Stage it whenever the pass read a staging inside a flush; the seam holds it with the frame, or the commit publishes it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2 * perf(signals): gate the pass-staged error on a running flush alone (#4109) flushTransaction implies nothing extra here once the pass is inside a flush: the one check covers the #4109 case and keeps the core floor at +2 B minified over next (was +7 B). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2 * fix(signals): a later pass replaces a staged error (#4109) CONFIG_STAGED_ERROR was cleared only at the commit. With a pass's own throw now staged whenever a flush runs, a memo that throws and re-runs in the same flush kept the flag: a value re-run was thrown as an error (its raw value reached the error arm, #4145), and a pending re-run left the superseded error to be published at the commit. A pass now drops an error staged by an earlier pass before it runs: its own answer (a value, a flight, or an error it stages again) replaces it. This folds in #4148's clear on the value path. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2 * chore(size): raise caps for the #4109 staged-error clear (Size-Exception) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2 --------- Co-authored-by: Claude <noreply@anthropic.com>
Generated by Claude Code |
…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>
Fixes #4145
Summary
When a memo throws while an async sibling holds the frame,
stageErrorputs the error in_pendingValueand setsCONFIG_STAGED_ERROR. If the memo recovers before that frame commits,recomputestages the value over it but leaves the flag set. At the reveal,servesees the flag and throws the value. That halts reactivity. The flag only got cleared incommitPendingNode, which runs after that read.Now the branch that stages a pass's value also clears
CONFIG_STAGED_ERROR.How did you test this change?
New
tests/held-error-recovery-4145.test.ts(the issue's repro, recovering to 1 and to 7). Before the fix, both cases halt with the value as the error and the sum stays 2. After it, they show 3 and 9.pnpm build && pnpm test: signals 5355 passed. The only failure, in web'sserver-functions-adapter-request.spec.tsx, also fails onnextwithout this change.Written with help from an AI assistant (Claude). I reviewed and tested the change myself.