EllanJiang/GameFramework · error · GameFrameworkException

State type is invalid.

Error message

State type is invalid.

What it means

In FsmState<T>.ChangeState(IFsm<T> fsm, Type stateType), after validating the FSM the library checks that stateType is non-null and assignable to FsmState<T>. It throws GameFrameworkException("State type is invalid.") when stateType is null, and a formatted variant when the type is not a valid state of this FSM.

Solutions

  1. Pass typeof(ConcreteStateClass) directly instead of reflection-resolved types
  2. If the Type comes from a string, null-check Type.GetType output before calling
  3. Ensure the target type derives from FsmState<T> for the same owner type T
  4. Prevent code stripping of state classes under IL2CPP (preserve attribute / link.xml)

Example fix

// before
Type stateType = Type.GetType(config.NextState); // may be null or wrong base
state.ChangeState(fsm, stateType);
// after
Type stateType = Type.GetType(config.NextState);
if (stateType != null && typeof(FsmState<Player>).IsAssignableFrom(stateType))
{
    state.ChangeState(fsm, stateType);
}
Defensive patterns

Strategy: validation

Validate before calling

if (stateType != null && typeof(FsmState<T>).IsAssignableFrom(stateType))
    ChangeState(fsm, stateType);

Type guard

static bool IsValidStateType<T>(Type t) where T : class => t != null && typeof(FsmState<T>).IsAssignableFrom(t);

Try / catch

try { ChangeState(fsm, stateType); }
catch (GameFrameworkException ex) { Log.Error("Invalid state type '{0}': {1}", stateType?.FullName, ex.Message); }

Prevention

When it happens

Trigger: Calling ChangeState(fsm, null); or passing a Type that does not derive from Fsm<T>'s state base (raises the related "State type '{0}' is invalid." message).

Common situations: Resolving state Type from string configs where the name is misspelled or the class was renamed/refactored (Type.GetType returns null); passing a state class belonging to a different FSM's owner type; stripped types in IL2CPP/AOT builds.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15). Data as JSON: /api/errors/70f1999b0ee03701. Report an issue: GitHub.

Appendix: source

Thrown at GameFramework/Fsm/FsmState.cs:99

            fsmImplement.ChangeState<TState>();
        }

        /// <summary>
        /// 切换当前有限状态机状态。
        /// </summary>
        /// <param name="fsm">有限状态机引用。</param>
        /// <param name="stateType">要切换到的有限状态机状态类型。</param>
        protected void ChangeState(IFsm<T> fsm, Type stateType)
        {
            Fsm<T> fsmImplement = (Fsm<T>)fsm;
            if (fsmImplement == null)
            {
                throw new GameFrameworkException("FSM is invalid.");
            }

            if (stateType == null)
            {
                throw new GameFrameworkException("State type is invalid.");
            }

            if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
            {
                throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
            }

            fsmImplement.ChangeState(stateType);
        }
    }
}

View on GitHub (pinned to d0c010b051)