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
- Pass a capacity of at least 1 (1 is the real minimum): useStateWithHistory(state, Math.max(1, capacity)).
- Validate/coerce dynamic values before the call and default to 10 (the library default) when invalid.
- If 0 capacity was intended to mean 'no history', use 1 instead, since the hook always tracks at least the current entry.
- 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
- Clamp dynamic capacity with Math.max(1, capacity) before passing.
- Default to the library's 10 when a config value is missing or non-positive.
- Remember the message is off-by-one: 1 is valid, only 0/negatives throw.
- Treat a configured 0 as 'use the default', not as a real capacity.
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
- useLocalStorage key may not be falsy
- states expected to be an object or array, got ${typeof state
- State '${state}' is not a valid state (does not exist in sta
- useReducerContext must be used inside a ReducerProvider.
- useStateContext must be used inside a StateProvider.
AI-assisted analysis of streamich/react-use@fbe99c6327 (2026-08-12).
Data as JSON: /api/errors/a17815487256c182.
Report an issue: GitHub.