Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[2.0] IMMUTABLE_UPDATE_IN_STORE false positive when an in-place `splice` shifts the next item into the removed index

Chiusa
#4,262 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

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

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

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di solidjs/solid

Tutte le issue di solidjs/solid

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.