EllanJiang/GameFramework · error · GameFrameworkException

FSM states is invalid.

Error message

FSM states is invalid.

What it means

Fsm<T>.Create requires at least one state to construct a usable state machine. The params overload validates states == null || states.Length < 1 at Fsm.cs:143 and throws this exception when the state array is missing or empty.

Solutions

  1. Pass at least one FsmState<T> instance to Create.
  2. If states are built dynamically, guard the call: only call Create when the array has Length >= 1.

Example fix

// before
FsmState<Enemy>[] states = CollectStates(); // may be empty
var fsm = Fsm<Enemy>.Create("Enemy", this, states);
// after
var states = CollectStates();
if (states != null && states.Length > 0)
{
    var fsm = Fsm<Enemy>.Create("Enemy", this, states);
}
Defensive patterns

Strategy: validation

Validate before calling

if (states == null || states.Length == 0)
{
    throw new InvalidOperationException("An FSM needs at least one state.");
}
var fsm = Fsm<Enemy>.Create("Enemy", this, states);

Type guard

bool HasStates<T>(FsmState<T>[] states) where T : class => states != null && states.Length > 0;

Try / catch

try { fsm = Fsm<Enemy>.Create("Enemy", this, states); }
catch (GameFrameworkException ex) { Log.Error("FSM states invalid: " + ex.Message); }

Prevention

When it happens

Trigger: Fsm<T>.Create(name, owner) with no state arguments, or Fsm<T>.Create(name, owner, (FsmState<T>[])null), or explicitly passing an empty FsmState<T>[0].

Common situations: Forgetting to list states in the params call; building the state array dynamically and ending up with an empty array; a config-driven setup where the state list failed to load.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at GameFramework/Fsm/Fsm.cs:143

        }

        /// <summary>
        /// 创建有限状态机。
        /// </summary>
        /// <param name="name">有限状态机名称。</param>
        /// <param name="owner">有限状态机持有者。</param>
        /// <param name="states">有限状态机状态集合。</param>
        /// <returns>创建的有限状态机。</returns>
        public static Fsm<T> Create(string name, T owner, params FsmState<T>[] states)
        {
            if (owner == null)
            {
                throw new GameFrameworkException("FSM owner is invalid.");
            }

            if (states == null || states.Length < 1)
            {
                throw new GameFrameworkException("FSM states is invalid.");
            }

            Fsm<T> fsm = ReferencePool.Acquire<Fsm<T>>();
            fsm.Name = name;
            fsm.m_Owner = owner;
            fsm.m_IsDestroyed = false;
            foreach (FsmState<T> state in states)
            {
                if (state == null)
                {
                    throw new GameFrameworkException("FSM states is invalid.");
                }

                Type stateType = state.GetType();
                if (fsm.m_States.ContainsKey(stateType))
                {
                    throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' state '{1}' is already exist.", new TypeNamePair(typeof(T), name), stateType.FullName));
                }

View on GitHub (pinned to d0c010b051)