{"record":{"id":"485cd1c83ac6de73","repo":"streamich/react-use","slug":"states-expected-to-be-an-object-or-array-got-ty","errorCode":null,"errorMessage":"states expected to be an object or array, got ${typeof states}","messagePattern":"states expected to be an object or array, got (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/useMultiStateValidator.ts","lineNumber":17,"sourceCode":"import { useCallback, useEffect, useRef, useState } from 'react';\nimport { StateValidator, UseStateValidatorReturn, ValidityState } from './useStateValidator';\n\nexport type MultiStateValidatorStates = any[] | { [p: string]: any } | { [p: number]: any };\nexport type MultiStateValidator<V extends ValidityState, S extends MultiStateValidatorStates> =\n  StateValidator<V, S>;\n\nexport function useMultiStateValidator<\n  V extends ValidityState,\n  S extends MultiStateValidatorStates\n>(\n  states: S,\n  validator: MultiStateValidator<V, S>,\n  initialValidity: V = [undefined] as V\n): UseStateValidatorReturn<V> {\n  if (typeof states !== 'object') {\n    throw new Error('states expected to be an object or array, got ' + typeof states);\n  }\n\n  const validatorInner = useRef(validator);\n  const statesInner = useRef(states);\n\n  validatorInner.current = validator;\n  statesInner.current = states;\n\n  const [validity, setValidity] = useState(initialValidity as V);\n\n  const validate = useCallback(() => {\n    if (validatorInner.current.length >= 2) {\n      validatorInner.current(statesInner.current, setValidity);\n    } else {\n      setValidity(validatorInner.current(statesInner.current));\n    }\n  }, [setValidity]);\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/streamich/react-use/blob/fbe99c6327e6af94df03bc8bd6ecc5e3ff04fbcc/src/useMultiStateValidator.ts#L1-L35","documentation":"Thrown by useMultiStateValidator when its first argument `states` is not of type 'object'. The hook expects a collection (an array or a record/object) of states to validate together, and rejects primitives up front. Caveat: the check is `typeof states !== 'object'`, and because typeof null === 'object', passing null bypasses this guard and will surface later as a different failure — the intended inputs are arrays and plain objects only.","triggerScenarios":"Calling useMultiStateValidator(states, validator, initialValidity) where states is a primitive (string, number, boolean, undefined, symbol, bigint). For example, passing a single state value instead of wrapping it in an array/object, or passing an optional prop that is undefined.","commonSituations":"Migrating from useStateValidator (single state) and forgetting to wrap the state in an array; passing an optional/derived prop that can be undefined; copy-paste where a primitive counter/flag is handed in directly.","solutions":["Pass states as an array or object: useMultiStateValidator([fieldA, fieldB], validator) or useMultiStateValidator({a, b}, validator).","If the value can be undefined, default it to an empty structure: useMultiStateValidator(states ?? [], validator).","Wrap a single state before passing: useMultiStateValidator([singleState], validator).","Do not pass null — although it slips past this check, it is not a valid states collection; use {} or [] instead."],"exampleFix":"// before\nuseMultiStateValidator(email, validateEmail);          // email is a primitive string\nuseMultiStateValidator(maybeStates, validator);         // maybeStates may be undefined\n\n// after\nuseMultiStateValidator([email], validateEmail);\nuseMultiStateValidator(maybeStates ?? [], validator);","handlingStrategy":"type-guard","validationCode":"function useMultiStateValidatorSafe<V extends ValidityState, S extends MultiStateValidatorStates>(\n  states: S,\n  validator: MultiStateValidator<V, S>,\n  initialValidity?: V\n) {\n  if (states === null || typeof states !== 'object') {\n    throw new Error('states must be a non-null object or array');\n  }\n  return useMultiStateValidator(states, validator, initialValidity);\n}\n\n// or coerce at the call site:\nconst safeStates = states ?? {};\nuseMultiStateValidator(safeStates, validator);","typeGuard":"// Accept arrays and plain objects; explicitly reject null (typeof null === 'object').\nconst isMultiState = (v: unknown): v is MultiStateValidatorStates =>\n  (Array.isArray(v) || (typeof v === 'object' && v !== null));\n\nif (isMultiState(states)) {\n  useMultiStateValidator(states, validator);\n}\n// else: handle the primitive case before calling","tryCatchPattern":"// The hook throws during render; wrap the consumer in a boundary rather than\n// try/catching the hook call, and fix the input via the type guard above.","preventionTips":["Always wrap a single state in an array ([state]) when migrating from useStateValidator.","Default optional states to [] or {} (states ?? []) before passing.","Never pass null — it passes the typeof check but is not a valid collection.","Type the parameter as MultiStateValidatorStates at the source so TypeScript catches primitives."],"tags":["react","hooks","validation","typescript"],"backgroundTag":null,"analyzedSha":"fbe99c6327e6af94df03bc8bd6ecc5e3ff04fbcc","analyzedAt":"2026-08-12T19:24:06.802Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}