[2.0] IMMUTABLE_UPDATE_IN_STORE false positive when an in-place `splice` shifts the next item into the removed index
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 55/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- javascript, typescript
- Ambito
- backend, testing-qa
Direzione di ricerca
Start in packages/signals/src/store/store.ts at reportReplacedContainers and trace how array writes from splice are checked; compare that with the array branch’s oldItems identity set. Read packages/signals/src/core/attribution.ts for checkImmutableUpdate, then reproduce the case in a dev build and check that moving an existing item emits no report while replacing it with a fresh similar object still does.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Version: solid-js / @solidjs/signals 2.0.0-rc.18, dev build. The relevant code is unchanged on next (4ea2f4986).
Description
Removing an item from a store array with an in-place splice (the repair the diagnostic itself recommends for arrays) can report IMMUTABLE_UPDATE_IN_STORE for the index the next item shifts into. This happens when the removed item and the one after it share at least half of their leaf values, for example two lines of the same product that differ only in one field.
No container was copied. After the splice, index 0 holds the object that was already at index 1.
Reproduction
Run in a dev build with the diagnostics observed (I used captureArtifact from @solidjs/diagnostics in a vitest jsdom test; the same message appears in the dev console):
import { createStore, flush } from 'solid-js'
const [, setState] = createStore({
items: [
{ id: 'a', product: 'p1', name: 'Pancakes', variant: 'meat', quantity: 2 },
{ id: 'b', product: 'p1', name: 'Pancakes', variant: 'cheese', quantity: 2 },
],
})
setState((draft) => {
draft.items.splice(0, 1)
})
flush()
No reader or effect is needed.
Actual
[IMMUTABLE_UPDATE_IN_STORE] "store.items.0" was replaced with a fresh object whose leaves are mostly the same values (3 of 5 unchanged, 2 changed) — a spread-copy update. The store already tracks leaves; a new container makes every reader of "store.items.0" re-run for the few that moved. Instead, assign the leaf on the draft (`store.items.0.<key> = …`) so only readers of that key re-run. For data arriving from outside (a fetch result), merge it with reconcile(data, key)(store.items.0).
Control: if the two items share fewer than half of their leaves (for example { id: 'b', product: 'p2', name: 'Soup', variant: 'cheese', quantity: 5 } as the second item), nothing is reported.
Expected
No report. The object now at items[0] is an item that was already in the same array before the write, so the write moved an existing item and did not replace it with a fresh copy. The suggested repair ("assign the leaf on the draft") does not apply here.
Code location
reportReplacedContainers in packages/signals/src/store/store.ts. For each written key it compares the leaves of the old and new object at that key. For an array index written by splice, the new value is the shifted sibling, so the leaf census compares two different existing items and checkImmutableUpdate (packages/signals/src/core/attribution.ts) sees "mostly the same values".
A possible fix is to skip the report when the new value at an array index is unwrapValue-identical to one of the old array's items (the same identity set the array branch already builds for oldItems), since that is a move and not a fresh container.
- Lingua principale
- TypeScript
- Stelle
- 36.2k
- Fork
- 1.1k
- Merge medio
- 10h 28m
- PR unite (30g)
- 379
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
-
`lazy()`: remounting an already-loaded component renders empty (or the Suspense fallback) since 1.9.14Forse già presa @itisrmk l’ha presa 11 giorni fa. Aperta1.x
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 51/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
solidjs/solid#4398 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Hydration runs an async memo over latest(...) of a hydrated chain with undefined and re-asksForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
-
[2.0 / next] A memo reading latest(a) beside b() computes a torn pass on a batched write; if that pass throws, the error sticksForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 4/5 1-2 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di solidjs/solid
Issue simili
-
area:plugins area:security area:skills bug has repro
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
anthropics/claude-code#105911 ·
I maintainer di solito rispondono entro 1 giorno
-
openspec-apply-change skill: when blocked, may select a ready artifact unrelated to missingArtifactsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Fission-AI/OpenSpec#2165 ·
I maintainer di solito rispondono entro 1 giorno
-
🐞 bug 🧐 unconfirmed
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
Tencent/tdesign-vue-next#7032 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
gnosis/gnosis_vpn#661 ·
I maintainer di solito rispondono entro 1 giorno
-
content-freshness: staleOwnedContent doc comments still say 'complete receipt' (follow-up to #7912)Apertatriage:bug-verified
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 92/100
I maintainer di solito rispondono entro 1 giorno