solidjs/solid · warning

Refusing to set "__proto__" on a store.

Error message

Refusing to set "__proto__" on a store.

What it means

setProperty, the internal writer used by the store setter, refuses to assign the key __proto__ and warns in dev. Assigning __proto__ on a store node would change the prototype of internal store data, corrupting the Proxy graph and enabling prototype-pollution-style bugs, so Solid no-ops it.

Source

Thrown at packages/solid/store/src/store.ts:235

  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 = false
): void {
  if (property === "__proto__") {
    if (IS_DEV) console.warn(`Refusing to set "__proto__" on a store.`);
    return;
  }
  if (!deleting && state[property] === value) return;
  const prev = state[property],
    len = state.length;

  if (IS_DEV)
    DevHooks.onStoreNodeUpdate && DevHooks.onStoreNodeUpdate(state, property, value, prev);

  if (value === undefined) {
    delete state[property];
    if (state[$HAS] && state[$HAS][property] && prev !== undefined) state[$HAS][property].$();
  } else {
    state[property] = value;
    if (state[$HAS] && state[$HAS][property] && prev === undefined) state[$HAS][property].$();
  }
  let nodes = getNodes(state, $NODE),
    node: DataNode | undefined;

View on GitHub (pinned to f47845f9cc)

Solutions

  1. Sanitize keys before applying: reject __proto__, constructor, prototype
  2. Use setStore(produce(...)) to apply changes programmatically on the draft instead of key-based paths
  3. Validate external objects with a schema (e.g. zod) before merging into stores

Example fix

// before
const patch = JSON.parse(body); // may contain __proto__
setStore(k, patch[k]) for all keys; // includes __proto__

// after
const safe = JSON.parse(body, (k, v) =>
  ['__proto__', 'constructor', 'prototype'].includes(k) ? undefined : v
);
setStore(produce(s => Object.assign(s, safe)));
Defensive patterns

Strategy: validation

Validate before calling

const UNSAFE = new Set(['__proto__', 'constructor', 'prototype']);
function safeAssign(setStore: Function, patch: Record<string, unknown>) {
  for (const [k, v] of Object.entries(patch)) if (!UNSAFE.has(k)) setStore(k, v);
}

Type guard

const isSafeKey = (k: PropertyKey): boolean =>
  typeof k === 'symbol' || !['__proto__', 'constructor', 'prototype'].includes(k);

Prevention

When it happens

Trigger: setStore('__proto__', payload), setState with a key computed from user input that equals __proto__, merging unvalidated JSON objects into a store where a __proto__ key survives unwrapping.

Common situations: Deep-merge utilities or Object.assign-style merging of API responses into stores; paths built from query params or form field names; migration from lodash.merge into setStore.

Related errors


AI-assisted analysis of solidjs/solid@f47845f9cc (2026-08-27). Data as JSON: /api/errors/f8e6b42c71eb425e. Report an issue: GitHub.