{"record":{"id":"2767b4f8c7e45eaf","repo":"solidjs/solid","slug":"cannot-mutate-a-store-directly","errorCode":null,"errorMessage":"Cannot mutate a Store directly","messagePattern":"Cannot mutate a Store directly","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/solid/store/src/store.ts","lineNumber":214,"sourceCode":"    return isWrappable(value) ? wrap(value) : value;\n  },\n\n  has(target, property) {\n    if (\n      property === $RAW ||\n      property === $PROXY ||\n      property === $TRACK ||\n      property === $NODE ||\n      property === $HAS ||\n      property === \"__proto__\"\n    )\n      return true;\n    getListener() && getNode(getNodes(target, $HAS), property)();\n    return property in target;\n  },\n\n  set() {\n    if (IS_DEV) console.warn(\"Cannot mutate a Store directly\");\n    return true;\n  },\n\n  deleteProperty() {\n    if (IS_DEV) console.warn(\"Cannot mutate a Store directly\");\n    return true;\n  },\n\n  ownKeys: ownKeys,\n\n  getOwnPropertyDescriptor: proxyDescriptor\n};\n\nexport function setProperty(\n  state: StoreNode,\n  property: PropertyKey,\n  value: any,\n  deleting: boolean = false","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/solidjs/solid/blob/f47845f9cc16ecbb316aa6560c7161f45af9a3d8/packages/solid/store/src/store.ts#L196-L232","documentation":"Store objects are wrapped in a Proxy whose set trap rejects direct assignment: state.field = value (in dev) warns 'Cannot mutate a Store directly'. Stores are intentionally immutable from the outside; all mutations must go through the setter returned by createStore so Solid can track and batch changes. The trap returns true so the assignment is swallowed, not applied.","triggerScenarios":"store.user = newUser, store.items.push(x), or store.items[i] = y executed directly on the store proxy instead of setStore('user', newUser) / setStore('items', i, y).","commonSituations":"Porting Vue/Svelte/MobX-style mutable code; passing the raw store into third-party libs that mutate their argument; refactor where a setter was accidentally replaced with assignment.","solutions":["Replace direct assignments with the setter: setStore('user', newUser)","For arrays use setStore('items', produce(list => list.push(x))) from solid-js/store","Wrap external mutators with produce/reconcile so mutation happens on the draft"],"exampleFix":"// before\nconst [state, setState] = createStore({ user: null });\nstate.user = { name: 'Ann' }; // warns, does nothing\n\n// after\nsetState('user', { name: 'Ann' });\n// or\nsetState(produce(s => { s.user = { name: 'Ann' }; }));","handlingStrategy":"validation","validationCode":"const [state, setState] = createStore(initial);\n// route all writes through setState:\nfunction updateUser(u: User) { setState('user', u); } // not state.user = u","typeGuard":"import { isProxy } from 'solid-js/store';\n// treat any store proxy as read-only; assert before mutating\nif (isProxy(target)) throw new Error('use the store setter, not assignment');","tryCatchPattern":null,"preventionTips":["Never assign or call mutators on store objects; always use the setter","Use produce for imperative edits on drafts","Hand external libraries copies (spread/structuredClone) rather than the store proxy"],"tags":["solid","store","mutation","proxy","dev-warning"],"backgroundTag":"illegal-direct-state-mutation","analyzedSha":"f47845f9cc16ecbb316aa6560c7161f45af9a3d8","analyzedAt":"2026-08-27T05:39:24.283Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}