EllanJiang/GameFramework · error · GameFrameworkException

FSM is invalid.

Error message

FSM is invalid.

What it means

DestroyFsm<T>(IFsm<T> fsm) destroys the FSM whose interface reference is given. The library throws GameFrameworkException("FSM is invalid.") when the fsm reference is null, as its Name and the owner type are needed to build the lookup key.

Solutions

  1. Null-check the IFsm reference before calling DestroyFsm
  2. Keep a valid reference from CreateFsm/GetFsm and avoid nulling it before destruction
  3. Call HasFsm<T>(name) first to confirm the FSM still exists and re-fetch it

Example fix

// before
if (m_Fsm == null) m_Fsm = fsmManager.GetFsm<Player>("movement");
fsmManager.DestroyFsm(m_Fsm); // still throws if null
// after
if (m_Fsm != null)
{
    fsmManager.DestroyFsm(m_Fsm);
    m_Fsm = null;
}
Defensive patterns

Strategy: validation

Validate before calling

if (fsm != null)
    fsmManager.DestroyFsm(fsm);

Type guard

static bool IsDestroyable<T>(IFsm<T> fsm) where T : class => fsm != null;

Try / catch

try { fsmManager.DestroyFsm(movementFsm); }
catch (GameFrameworkException ex) { Log.Error("DestroyFsm failed: {0}", ex.Message); }
finally { movementFsm = null; }

Prevention

When it happens

Trigger: Calling DestroyFsm<T>(null) — null interface reference passed as the argument.

Common situations: Storing an IFsm<T> in a field that was never assigned (creation failed earlier); FSM already destroyed elsewhere and the reference cleared to null; Unity scene reload leaving stale null references.

Related errors


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

Appendix: source

Thrown at GameFramework/Fsm/FsmManager.cs:362

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

            return InternalDestroyFsm(new TypeNamePair(ownerType, name));
        }

        /// <summary>
        /// 销毁有限状态机。
        /// </summary>
        /// <typeparam name="T">有限状态机持有者类型。</typeparam>
        /// <param name="fsm">要销毁的有限状态机。</param>
        /// <returns>是否销毁有限状态机成功。</returns>
        public bool DestroyFsm<T>(IFsm<T> fsm) where T : class
        {
            if (fsm == null)
            {
                throw new GameFrameworkException("FSM is invalid.");
            }

            return InternalDestroyFsm(new TypeNamePair(typeof(T), fsm.Name));
        }

        /// <summary>
        /// 销毁有限状态机。
        /// </summary>
        /// <param name="fsm">要销毁的有限状态机。</param>
        /// <returns>是否销毁有限状态机成功。</returns>
        public bool DestroyFsm(FsmBase fsm)
        {
            if (fsm == null)
            {
                throw new GameFrameworkException("FSM is invalid.");
            }

            return InternalDestroyFsm(new TypeNamePair(fsm.OwnerType, fsm.Name));

View on GitHub (pinned to d0c010b051)