solidjs/solid · warning
Cannot mutate a Store directly
Error message
Cannot mutate a Store directly
What it means
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.
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
Example fix
// before
const [state, setState] = createStore({ user: null });
state.user = { name: 'Ann' }; // warns, does nothing
// after
setState('user', { name: 'Ann' });
// or
setState(produce(s => { s.user = { name: 'Ann' }; })); Defensive patterns
Strategy: validation
Validate before calling
const [state, setState] = createStore(initial);
// route all writes through setState:
function updateUser(u: User) { setState('user', u); } // not state.user = u Type guard
import { isProxy } from 'solid-js/store';
// treat any store proxy as read-only; assert before mutating
if (isProxy(target)) throw new Error('use the store setter, not assignment'); Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Refusing to set "__proto__" on a store.
- Refusing to traverse unsafe key
- cleanups created outside a `createRoot` or `render` will…
- computations created outside a `createRoot` or `render`…
- error handlers created outside a `createRoot` or `render`…
AI-assisted analysis of solidjs/solid@f47845f9cc (2026-08-27).
Data as JSON: /api/errors/2767b4f8c7e45eaf.
Report an issue: GitHub.
Appendix: source
Thrown at packages/solid/store/src/store.ts:214
return isWrappable(value) ? wrap(value) : value;
},
has(target, property) {
if (
property === $RAW ||
property === $PROXY ||
property === $TRACK ||
property === $NODE ||
property === $HAS ||
property === "__proto__"
)
return true;
getListener() && getNode(getNodes(target, $HAS), property)();
return property in target;
},
set() {
if (IS_DEV) console.warn("Cannot mutate a Store directly");
return true;
},
deleteProperty() {
if (IS_DEV) console.warn("Cannot mutate a Store directly");
return true;
},
ownKeys: ownKeys,
getOwnPropertyDescriptor: proxyDescriptor
};
export function setProperty(
state: StoreNode,
property: PropertyKey,
value: any,
deleting: boolean = falseView on GitHub (pinned to f47845f9cc)