streamich/react-use · error · Error
State '${state}' is not a valid state (does not exist in sta
Error message
State '${state}' is not a valid state (does not exist in state list) What it means
Thrown by the `setState` function returned from useStateList when the requested state value is not present in the configured state list. Internally setState looks up the index via stateSet.indexOf(state); if it returns -1 (not found), the library refuses to move to a non-existent state and throws. There is an isMounted() guard first, so the throw only occurs while the component is mounted.
Source
Thrown at src/useStateList.ts:60
if (newIndex === index.current) return;
// it gives the ability to travel through the left and right borders.
// 4ex: if list contains 5 elements, attempt to set index 9 will bring use to 5th element
// in case of negative index it will start counting from the right, so -17 will bring us to 4th element
index.current =
newIndex >= 0
? newIndex % stateSet.length
: stateSet.length + (newIndex % stateSet.length);
update();
},
setState: (state: T) => {
// do nothing on unmounted component
if (!isMounted()) return;
const newIndex = stateSet.length ? stateSet.indexOf(state) : -1;
if (newIndex === -1) {
throw new Error(`State '${state}' is not a valid state (does not exist in state list)`);
}
index.current = newIndex;
update();
},
}),
[stateSet]
);
return {
state: stateSet[index.current],
currentIndex: index.current,
isFirst: index.current === 0,
isLast: index.current === stateSet.length - 1,
...actions,
};
}
View on GitHub (pinned to fbe99c6327)
Solutions
- Pass only values that exist in the state list; reference the same constants/literals used to build the list.
- Validate membership before calling: if (states.includes(next)) setState(next); else handle the unknown state.
- For object states, compare by a stable key/id rather than passing a newly-constructed object, or store the canonical members and reuse references.
- Double-check casing/whitespace of string states against the list definition.
Example fix
// before
const [state, controls] = useStateList(['open', 'closed', 'pending']);
controls.setState('Open'); // throws: 'open' !== 'Open'
// after
controls.setState('open');
// or guard:
if (['open','closed','pending'].includes(next)) controls.setState(next); Defensive patterns
Strategy: validation
Validate before calling
const states = ['open', 'closed', 'pending'] as const;
const [, controls] = useStateList(states);
function safeSetState(next: string) {
if (states.includes(next as (typeof states)[number])) {
controls.setState(next);
} else {
console.warn(`Unknown state: ${next}`);
}
} Type guard
const STATES = ['open', 'closed', 'pending'] as const; type State = (typeof STATES)[number]; const isState = (v: unknown): v is State => typeof v === 'string' && (STATES as readonly string[]).includes(v); if (isState(next)) controls.setState(next); // else: ignore or log — never call setState with an unknown value
Try / catch
try {
controls.setState(next);
} catch (e) {
// setState is user-triggered (not render), so try/catch is viable here:
console.warn(`Rejected state transition to '${next}': not in list`, e);
} Prevention
- Define the state list as a single source of truth (const array / enum) and derive the type from it.
- Validate membership with a type guard before calling setState, especially for external/deserialized values.
- For object states, compare by a stable id/key rather than a freshly-constructed object.
- Watch for casing/whitespace mismatches in string states.
When it happens
Trigger: Calling controls.setState(someValue) where someValue is not an element of the state list passed to useStateList. Examples: a typo in an enum/union value, a value from a different casing, or an externally-derived value that does not exactly match a list member (also affected by reference equality for object states).
Common situations: String/enum mismatches ('Open' vs 'open'); copy-pasting a state machine whose labels differ; object states compared by reference where a fresh object is passed instead of the original list member; deserialized JSON values that do not match the literal list entries.
Related errors
- useLocalStorage key may not be falsy
- states expected to be an object or array, got ${typeof state
- Capacity has to be greater than 1, got '${capacity}'
- 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/6a4d4d638cf3dda4.
Report an issue: GitHub.