streamich/react-use · error · Error

useLocalStorage key may not be falsy

Error message

useLocalStorage key may not be falsy

What it means

Thrown by useLocalStorage when its `key` argument is falsy. The hook runs an SSR short-circuit first (returns [initialValue, noop, noop] when not in a browser), so this check only executes client-side; once there, any falsy key (empty string '', 0, false, null, undefined, NaN) is rejected because localStorage cannot be keyed by such a value. Passing a non-string key would also fail at the storage API, so the library fails fast with a clear message instead.

Source

Thrown at src/useLocalStorage.ts:23

  | {
      raw: true;
    }
  | {
      raw: false;
      serializer: (value: T) => string;
      deserializer: (value: string) => T;
    };

const useLocalStorage = <T>(
  key: string,
  initialValue?: T,
  options?: parserOptions<T>
): [T | undefined, Dispatch<SetStateAction<T | undefined>>, () => void] => {
  if (!isBrowser) {
    return [initialValue as T, noop, noop];
  }
  if (!key) {
    throw new Error('useLocalStorage key may not be falsy');
  }

  const deserializer = options
    ? options.raw
      ? (value) => value
      : options.deserializer
    : JSON.parse;

  // eslint-disable-next-line react-hooks/rules-of-hooks
  const initializer = useRef((key: string) => {
    try {
      const serializer = options ? (options.raw ? String : options.serializer) : JSON.stringify;

      const localStorageValue = localStorage.getItem(key);
      if (localStorageValue !== null) {
        return deserializer(localStorageValue);
      } else {
        initialValue && localStorage.setItem(key, serializer(initialValue));

View on GitHub (pinned to fbe99c6327)

Solutions

  1. Provide a stable, non-empty string key: useLocalStorage(`item-${id}`, initialValue) and ensure the interpolated value is defined.
  2. Guard before calling: if (!key) return fallback; else call the hook — or compute key with a guaranteed prefix/default.
  3. If the key depends on async data, render the component using useLocalStorage only after the key is known (conditional rendering), or lift the key to a parent.
  4. Stringify numeric ids and avoid using 0/false as keys.

Example fix

// before
useLocalStorage(userId, defaultPrefs);        // userId may be 0 or undefined
useLocalStorage(maybeKey, defaultPrefs);       // maybeKey may be '' or undefined

// after
useLocalStorage(`user:${userId}`, defaultPrefs);
// or skip until known:
if (!maybeKey) return <Fallback/>;
useLocalStorage(maybeKey, defaultPrefs);
Defensive patterns

Strategy: validation

Validate before calling

function useLocalStorageSafe<T>(key: string, initial?: T, opts?: parserOptions<T>) {
  if (!key || typeof key !== 'string') {
    throw new Error('useLocalStorage requires a non-empty string key');
  }
  return useLocalStorage<T>(key, initial, opts);
}

// or coerce at the call site:
const storageKey = key ? `ns:${key}` : 'ns:default';
const [val, setVal] = useLocalStorage(storageKey, initial);

Type guard

const isStorageKey = (v: unknown): v is string =>
  typeof v === 'string' && v.length > 0;

if (isStorageKey(key)) {
  const [val, setVal] = useLocalStorage(key, initial);
}
// else branch: key not ready — render a fallback / skip the hook

Try / catch

// Hooks cannot be wrapped in try/catch around the call cleanly; instead guard the
// key before calling. If you must isolate, render the hook behind a gate:
{hasKey ? <UsesLocalStorage/> : <Fallback/>}

Prevention

When it happens

Trigger: Calling useLocalStorage(key, initialValue, options) where key evaluates to a falsy value: an empty string, undefined (e.g. from an unset prop/env), null, 0, or false. Typically the key is derived from a prop, route param, or config that has not resolved yet.

Common situations: Key built from an optional prop (id ?? '') producing ''; reading a key from env/config that is undefined in some environments; dynamic keys computed before data loads; passing a numeric id (0 is falsy) instead of a stringified storage key.

Related errors


AI-assisted analysis of streamich/react-use@fbe99c6327 (2026-08-12). Data as JSON: /api/errors/3355963164eea400. Report an issue: GitHub.