[2.0 / next] A keyed Show on latest() of a staged write mounts its child twice when the flush parks (regressed by #4393)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- javascript, typescript
Direzione di ricerca
Start with the failing matrix rows in packages/signals/tests/boundary-not-born-held-3540.test.ts and the equivalent cases in packages/web/test/loading-on-keyed-boundary-3540.spec.tsx. Read the linked design notes D-2 and D-22 and the reader-seat rebuild plan in #4395 to understand the intended in-place park re-derive. Done means both cases produce mount counts [1, 2, 2] while preserving the stated latest() behavior.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
A keyed <Show when={latest(count)}> whose when reads a write that is staged in the current flush but not yet held mounts its child twice when that flush parks. The pass runs provisionally (reads latest(count) → new value, the keyed Show mounts the child for key 2), the flush parks on a pending async read, and the pass is re-derived once as a verdict reader (D-2). Because the provisional owner was voided before the re-run, the keyed comparison is against the last committed when, so the same key mounts a second child. Mount side effects run twice for one key change. This regressed with #4393 (which was itself correct for #4365) and is currently pinned at the wrong number.
Reproduction
Signals-level (packages/signals/tests/boundary-not-born-held-3540.test.ts, matrix rows static over latest / callback over latest); web-level equivalent in packages/web/test/loading-on-keyed-boundary-3540.spec.tsx (show-static-latest, show-callback-latest):
const [count, setCount] = createSignal(1);
const data = createMemo(async () => { const v = count(); await delay(1000); return v; });
let mounts = 0;
const L = () => { mounts++; return <Loading fallback="Loading A">{data()}</Loading>; };
<Show keyed when={latest(count)}><L /></Show>
<Loading fallback="Loading B">{data()}</Loading> // B holds the frame on data (A33)
- Render; advance 1000ms; flush →
mounts === 1. setCount(2); flush(); await microtask; flush()— the frame parks ondata; A showsLoading Aearly (correct).mountsis 3; expected 2.- Advance 1000ms; flush →
2|2|2;mountsstays at the mid-flight count.
Observed [1, 3, 3], expected [1, 2, 2]. The <L /> factory (and anything a real child would do on mount — effects, refs, subscriptions) runs twice for a single key change.
Why it is a bug
- D-2 says a provisional pass that read a staging not yet held is re-derived at the park. It says nothing about discarding the pass's output.
latest()serves the staging on both runs (D-22, 2026-10-28 paragraph: "Inside a flush,latest()of a staging not yet held is the frame's read like any other"), so the key is identical across the two runs. Same key → one child → one mount.- No rule licenses a mount that depends on whether a flush happened to park. It is a timing-dependent double invocation. A remount is only correct when the verdict run yields a different key — an ordinary keyed change.
History
- #3540 added a
!probingarm toprovisionalVerdict("a provisional pass re-derived at the seam ran everything downstream of it twice (#3540 web)"), which produced[1, 2, 2]. - #4393 removed that arm to fix #4365 — correctly:
latest()must not open a transaction for its verdict — and re-pinned both tests to[1, 3, 3]with a "not a bug" comment. The removal was right; the re-pin was not.
Intended fix
An in-place park re-derive: re-run the pass under the same owner, with keyed children compared against the provisional run rather than the last commit. Scheduled for the reader-seat rebuild S1 (#4395). Explicitly not: restoring the !probing arm, the stagedScreen transaction variant, or letting latest() open a transaction.
Interim
The companion PR flips both pins to it.fails asserting the target [1, 2, 2], so they turn green when fixed instead of guarding the wrong number. List under known bugs in the next RC notes.
- Lingua principale
- TypeScript
- Stelle
- 36.2k
- Fork
- 1.1k
- Merge medio
- 11h 5m
- PR unite (30g)
- 475
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di solidjs/solid
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 28/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 12/100
I maintainer di solito rispondono entro 1 giorno
-
[2.0 / next] <Errored> recovery shows a pending memo's answer to an older input beside the new inputAperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 20/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 15/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 18/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di solidjs/solid
Issue simili
-
needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
microsoft/playwright#43875 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
calagopus/panel#285 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 88/100
adobe/react-spectrum#10909 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Run the dependency drift checkForse già presa @spaceninja l’ha presa oggi. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
cloudfour/lighthouse-parade#449 ·
I maintainer di solito rispondono entro 1 giorno