mantinedev/mantine · error · Error

@mantine/hooks ${hookName}: Failed to serialize the value

Error message

@mantine/hooks ${hookName}: Failed to serialize the value

What it means

The use-local-storage family of hooks (useLocalStorage, useLocalStorageWithNativeEvents, useDebouncedValue users of createStorage, useSessionStorage) JSON.stringify values before writing them. If the value contains something non-serializable (circular references, BigInt, functions), stringification fails and this wrapper error is thrown.

Source

Thrown at packages/@mantine/hooks/src/use-local-storage/create-storage.ts:31

  /** If set to true, value will be updated in useEffect after mount. Default value is true. */
  getInitialValueInEffect?: boolean;

  /** Determines whether the value must be synced between browser tabs, `true` by default */
  sync?: boolean;

  /** Function to serialize value into string to be save in storage */
  serialize?: (value: T) => string;

  /** Function to deserialize string value from storage to value */
  deserialize?: (value: string | undefined) => T;
}

function serializeJSON<T>(value: T, hookName: string = 'use-local-storage') {
  try {
    return JSON.stringify(value);
  } catch (error) {
    throw new Error(`@mantine/hooks ${hookName}: Failed to serialize the value`);
  }
}

function deserializeJSON(value: string | undefined) {
  try {
    return value && JSON.parse(value);
  } catch {
    return value;
  }
}

function createStorageHandler(type: StorageType) {
  const getItem = (key: string) => {
    try {
      return window[type].getItem(key);
    } catch (error) {
      console.warn('use-local-storage: Failed to get value from storage, localStorage is blocked');
      return null;

View on GitHub (pinned to 8a284e2c2c)

Solutions

  1. Store a serializable plain representation: convert dates to ISO strings, break circular references, stringify BigInts
  2. Use a custom serializer or write a toStorage/fromStorage wrapper that safely transforms the value
  3. If the value is inherently non-serializable, keep it in state/memory instead of localStorage

Example fix

// before
useLocalStorage({ key: 'node', value: someDomNode }); // circular

// after
useLocalStorage({ key: 'tag', value: { id: 1, name: 'x' } }); // plain serializable object
Defensive patterns

Strategy: validation

Validate before calling

function isSerializable(value: unknown): boolean {
  try {
    JSON.stringify(value);
    return true;
  } catch {
    return false;
  }
}

if (!isSerializable(value)) {
  // store a simplified copy instead
}

Type guard

function isPlainSerializable(v: unknown): boolean {
  return (
    v === null ||
    ['string', 'number', 'boolean'].includes(typeof v) ||
    (Array.isArray(v) && v.every(isPlainSerializable)) ||
    (typeof v === 'object' &&
      Object.values(v).every((x) => x !== undefined && !BigUint64Array && typeof x !== 'function') &&
      Object.values(v).every(isPlainSerializable))
  );
}

Prevention

When it happens

Trigger: Storing an object with a circular reference (e.g. a DOM node, class instance with back-references); storing BigInt values; storing functions or class instances like dayjs objects with cyclic internals.

Common situations: Caching React refs or DOM elements; persisting ORM/model instances or dayjs/Date-like objects with cycles; JSON.stringify quirks with BigInt after a schema change to include ids as BigInt.

Related errors


AI-assisted analysis of mantinedev/mantine@8a284e2c2c (2026-08-28). Data as JSON: /api/errors/1833087ba661513a. Report an issue: GitHub.