streamich/react-use · error · Error

Capacity has to be greater than 1, got '${capacity}'

Error message

Capacity has to be greater than 1, got '${capacity}'

What it means

Thrown by useStateWithHistory when its `capacity` argument is less than 1. The hook defaults capacity to 10, so this only triggers when a caller explicitly passes 0 or a negative number. Note the message says 'greater than 1' but the actual guard is `capacity < 1`, so a capacity of exactly 1 IS valid — the message wording is slightly inaccurate (it should read 'at least 1' / 'greater than 0').

Source

Thrown at src/useStateWithHistory.ts:29

  go: (position: number) => void;
}

export type UseStateHistoryReturn<S> = [S, Dispatch<IHookStateSetAction<S>>, HistoryState<S>];

export function useStateWithHistory<S, I extends S>(
  initialState: IHookStateInitAction<S>,
  capacity?: number,
  initialHistory?: I[]
): UseStateHistoryReturn<S>;
export function useStateWithHistory<S = undefined>(): UseStateHistoryReturn<S | undefined>;

export function useStateWithHistory<S, I extends S>(
  initialState?: IHookStateInitAction<S>,
  capacity: number = 10,
  initialHistory?: I[]
): UseStateHistoryReturn<S> {
  if (capacity < 1) {
    throw new Error(`Capacity has to be greater than 1, got '${capacity}'`);
  }

  const isFirstMount = useFirstMountState();
  const [state, innerSetState] = useState<S>(initialState as S);
  const history = useRef<S[]>((initialHistory ?? []) as S[]);
  const historyPosition = useRef(0);

  // do the states manipulation only on first mount, no sense to load re-renders with useless calculations
  if (isFirstMount) {
    if (history.current.length) {
      // if last element of history !== initial - push initial to history
      if (history.current[history.current.length - 1] !== initialState) {
        history.current.push(initialState as I);
      }

      // if initial history bigger that capacity - crop the first elements out
      if (history.current.length > capacity) {
        history.current = history.current.slice(history.current.length - capacity);

View on GitHub (pinned to fbe99c6327)

Solutions

  1. Pass a capacity of at least 1 (1 is the real minimum): useStateWithHistory(state, Math.max(1, capacity)).
  2. Validate/coerce dynamic values before the call and default to 10 (the library default) when invalid.
  3. If 0 capacity was intended to mean 'no history', use 1 instead, since the hook always tracks at least the current entry.
  4. Treat the error message's 'greater than 1' as imprecise — verify against the code (capacity < 1 throws).

Example fix

// before
useStateWithHistory(state, historyLimit);   // historyLimit may be 0 or negative
useStateWithHistory(state, 0);

// after
useStateWithHistory(state, Math.max(1, historyLimit));
useStateWithHistory(state, 1);  // valid: 1 is allowed
Defensive patterns

Strategy: validation

Validate before calling

function useStateWithHistorySafe<S, I extends S>(
  initialState: IHookStateInitAction<S>,
  capacity: number,
  initialHistory?: I[]
) {
  // Real minimum is 1 (guard is `capacity < 1`), despite the 'greater than 1' message.
  const safeCapacity = Number.isFinite(capacity) && capacity >= 1 ? capacity : 10;
  return useStateWithHistory<S, I>(initialState, safeCapacity, initialHistory);
}

Type guard

const isPositiveCapacity = (v: unknown): v is number =>
  typeof v === 'number' && Number.isFinite(v) && v >= 1;

const cap = isPositiveCapacity(rawCapacity) ? rawCapacity : 10;
const [state, setState, history] = useStateWithHistory(initial, cap);

Try / catch

// The throw occurs on first render inside the hook; validate capacity before
// calling instead of try/catching the hook invocation.

Prevention

When it happens

Trigger: Calling useStateWithHistory(initialState, capacity, initialHistory) with capacity set to 0 or a negative number, e.g. from a dynamic/config value that underflows. With no argument (default 10) or capacity >= 1, no throw occurs.

Common situations: Capacity derived from config/user input that can be 0 (e.g. a 'history length' setting set to 0); arithmetic that subtracts and goes negative; passing undefined through a defaulted-to-0 chain; misunderstanding the off-by-one message and testing the wrong boundary.

Related errors


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