{"record":{"id":"e4126e2159f4415b","repo":"greensock/GSAP","slug":"not-a-valid-state-object","errorCode":null,"errorMessage":"Not a valid state object.","messagePattern":"Not a valid state object\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/Flip.js","lineNumber":323,"sourceCode":"\t\t\t\t_bodyLocked= lock;\n\t\t\t} else if (_bodyLocked) {\n\t\t\t\twhile (i--) {\n\t\t\t\t\t_bodyMetrics[i] ? (s[_bodyProps[i]] = _bodyMetrics[i]) : s.removeProperty(_camelToDashed(_bodyProps[i]));\n\t\t\t\t}\n\t\t\t\t_bodyLocked = lock;\n\t\t\t}\n\t\t}\n\t},\n\t_revertTempStyles = (temps, stateIndex) => { // in _fromTo(), we store the inline styles temporarily when nested is true, and the Array is like [element, styles1, styles2, element, styles1, styles2, ...] where styles1 is one state and styles2 is another state (the element.getAttribute(\"style\")).\n\t\tfor (let i = 0; i < temps.length; i+=3) {\n\t\t\tgsap.set(temps[i], {clearProps: true}); // to clear cached transforms too\n\t\t\ttemps[i].setAttribute(\"style\", temps[i+stateIndex]);\n\t\t\ttemps[i]._gsap.gmCache = -1; // bust the globalMatrix cache\n\t\t}\n\t},\n\n\t_fromTo = (fromState, toState, vars, relative) => { // relative is -1 if \"from()\", and 1 if \"to()\"\n\t\t(fromState instanceof FlipState && toState instanceof FlipState) || console.warn(\"Not a valid state object.\");\n\t\tvars = vars || {};\n\t\tlet { clearProps, onEnter, onLeave, absolute, absoluteOnLeave, custom, delay, paused, repeat, repeatDelay, yoyo, toggleClass, nested, zIndex, scale, fade, stagger, spin, prune } = vars,\n\t\t\tprops = (\"props\" in vars ? vars : fromState).props,\n\t\t\ttweenVars = _copy(vars, _reserved),\n\t\t\tanimation = gsap.timeline({ delay, paused, repeat, repeatDelay, yoyo, data: \"isFlip\" }),\n\t\t\tremainingProps = tweenVars,\n\t\t\tentering = [],\n\t\t\tleaving = [],\n\t\t\tcomps = [],\n\t\t\tswapOutTargets = [],\n\t\t\tspinNum = spin === true ? 1 : spin || 0,\n\t\t\tspinFunc = typeof(spin) === \"function\" ? spin : () => spinNum,\n\t\t\tinterrupted = fromState.interrupted || toState.interrupted,\n\t\t\taddFunc = animation[relative !== 1 ? \"to\" : \"from\"],\n\t\t\tv, p, endTime, i, el, comp, state, targets, finalStates, fromNode, toNode, run, a, b;\n\t\t//relative || (toState = (new FlipState(toState.targets, {props: props})).fit(toState, scale));\n\t\tfor (p in toState.idLookup) {\n\t\t\ttoNode = !toState.alt[p] ? toState.idLookup[p] : _getChangingElState(toState, fromState, p);","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/greensock/GSAP/blob/13e2b790546426a1a2e0e9b409f3f8dc6d6611f2/src/Flip.js#L305-L341","documentation":"Flip's _fromTo (backing Flip.from/Flip.to) requires both fromState and toState to be FlipState instances. If either argument is not a valid state object (e.g. undefined, a plain object, or the result of a failed getState), it warns \"Not a valid state object.\" and proceeds only after the check, risking downstream errors.","triggerScenarios":"Passing a plain object instead of Flip.getState() output to Flip.from()/Flip.to(); a Flip.getState() call that failed/was overwritten; JSON-serialized state (loses class identity so instanceof FlipState fails); passing state from a different Flip copy.","commonSituations":"Persisting state to localStorage/JSON and restoring it; two bundled copies of Flip so instanceof checks fail; typo like Flip.from(state.vars); calling Flip.from() with no argument.","solutions":["Always pass the return value of Flip.getState() directly","Never serialize/deserialize FlipState through JSON — re-capture state instead","Ensure one copy of Flip/gsap in the bundle","Check Flip.from(state) receives a truthy state (log it if unsure)"],"exampleFix":"// before\nconst saved = JSON.parse(localStorage.getItem('flipState'));\nFlip.from(saved); // plain object, not FlipState\n// after\n// re-capture state in the live DOM instead of persisting class instances\nconst state = Flip.getState('.card');\nFlip.from(state);","handlingStrategy":"validation","validationCode":"if (!(fromState instanceof FlipState) || !(toState instanceof FlipState)) {\n  throw new Error('Flip.from/to require FlipState objects from Flip.getState()');\n}","typeGuard":"function isFlipState(s) {\n  return s instanceof FlipState || (s && s.idLookup && s.elementStates && Array.isArray(s.elementStates));\n}","tryCatchPattern":"try {\n  Flip.from(state);\n} catch (err) {\n  console.error('Flip state invalid — re-capture with Flip.getState()', err);\n  state = Flip.getState('.target');\n  Flip.from(state);\n}","preventionTips":["Never serialize FlipState to JSON — re-capture instead","Pass Flip.getState() output directly to Flip.from/to","Keep a single Flip/gsap bundle copy","Log state before passing to verify it is a FlipState"],"tags":["flip","invalid-argument","state","type-error"],"backgroundTag":"invalid-state-object","analyzedSha":"13e2b790546426a1a2e0e9b409f3f8dc6d6611f2","analyzedAt":"2026-08-29T08:34:05.027Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}