greensock/GSAP · warning
Not a valid state object.
Error message
Not a valid state object.
What it means
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.
Source
Thrown at src/Flip.js:323
_bodyLocked= lock;
} else if (_bodyLocked) {
while (i--) {
_bodyMetrics[i] ? (s[_bodyProps[i]] = _bodyMetrics[i]) : s.removeProperty(_camelToDashed(_bodyProps[i]));
}
_bodyLocked = lock;
}
}
},
_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")).
for (let i = 0; i < temps.length; i+=3) {
gsap.set(temps[i], {clearProps: true}); // to clear cached transforms too
temps[i].setAttribute("style", temps[i+stateIndex]);
temps[i]._gsap.gmCache = -1; // bust the globalMatrix cache
}
},
_fromTo = (fromState, toState, vars, relative) => { // relative is -1 if "from()", and 1 if "to()"
(fromState instanceof FlipState && toState instanceof FlipState) || console.warn("Not a valid state object.");
vars = vars || {};
let { clearProps, onEnter, onLeave, absolute, absoluteOnLeave, custom, delay, paused, repeat, repeatDelay, yoyo, toggleClass, nested, zIndex, scale, fade, stagger, spin, prune } = vars,
props = ("props" in vars ? vars : fromState).props,
tweenVars = _copy(vars, _reserved),
animation = gsap.timeline({ delay, paused, repeat, repeatDelay, yoyo, data: "isFlip" }),
remainingProps = tweenVars,
entering = [],
leaving = [],
comps = [],
swapOutTargets = [],
spinNum = spin === true ? 1 : spin || 0,
spinFunc = typeof(spin) === "function" ? spin : () => spinNum,
interrupted = fromState.interrupted || toState.interrupted,
addFunc = animation[relative !== 1 ? "to" : "from"],
v, p, endTime, i, el, comp, state, targets, finalStates, fromNode, toNode, run, a, b;
//relative || (toState = (new FlipState(toState.targets, {props: props})).fit(toState, scale));
for (p in toState.idLookup) {
toNode = !toState.alt[p] ? toState.idLookup[p] : _getChangingElState(toState, fromState, p);View on GitHub (pinned to 13e2b79054)
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)
Example fix
// before
const saved = JSON.parse(localStorage.getItem('flipState'));
Flip.from(saved); // plain object, not FlipState
// after
// re-capture state in the live DOM instead of persisting class instances
const state = Flip.getState('.card');
Flip.from(state); Defensive patterns
Strategy: validation
Validate before calling
if (!(fromState instanceof FlipState) || !(toState instanceof FlipState)) {
throw new Error('Flip.from/to require FlipState objects from Flip.getState()');
} Type guard
function isFlipState(s) {
return s instanceof FlipState || (s && s.idLookup && s.elementStates && Array.isArray(s.elementStates));
} Try / catch
try {
Flip.from(state);
} catch (err) {
console.error('Flip state invalid — re-capture with Flip.getState()', err);
state = Flip.getState('.target');
Flip.from(state);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of greensock/GSAP@13e2b79054 (2026-08-29).
Data as JSON: /api/errors/e4126e2159f4415b.
Report an issue: GitHub.