EllanJiang/GameFramework · error · GameFrameworkException

Current state is invalid.

Error message

Current state is invalid.

What it means

The internal ChangeState(Type) requires the FSM to currently be in a state (m_CurrentState != null) because it calls OnLeave on the outgoing state. If the FSM has no current state — e.g. it has not started or has already shut down — GameFrameworkException('Current state is invalid.') is thrown.

Solutions

  1. Ensure the FSM was created with a valid start state and has entered it before changing state
  2. Only call ChangeState from within state OnUpdate/OnLeave flows or after the FSM is running
  3. Check FSM lifetime management so Shutdown does not race with ChangeState calls
  4. Verify CreateFsm was given a states array containing the intended start state

Example fix

// before
fsm.ChangeState(typeof(MoveState)); // may run before FSM started
// after
if (fsm.CurrentState != null)
{
    fsm.ChangeState(typeof(MoveState));
}
Defensive patterns

Strategy: validation

Validate before calling

if (fsm == null || fsm.CurrentState == null) throw new InvalidOperationException("FSM not started");

Type guard

bool CanChangeState(Fsm<T> fsm) => fsm != null && fsm.CurrentState != null;

Try / catch

try { fsm.ChangeState(typeof(TargetState)); } catch (GameFrameworkException ex) when (ex.Message == "Current state is invalid.") { /* FSM not running: re-init or queue transition */ }

Prevention

When it happens

Trigger: Calling ChangeState before the FSM's Start/Poll sets an initial state; calling ChangeState from outside the state lifecycle after Shutdown cleared m_CurrentState; an FSM created with no states so no initial state was entered.

Common situations: Triggering a state change from game logic before the FSM update loop ran once; race conditions where Shutdown ran on another thread/tick; constructing an Fsm without registering the state the Start call should enter.

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/1b002ec91243744d. Report an issue: GitHub.

Appendix: source

Thrown at GameFramework/Fsm/Fsm.cs:573

        /// <summary>
        /// 切换当前有限状态机状态。
        /// </summary>
        /// <typeparam name="TState">要切换到的有限状态机状态类型。</typeparam>
        internal void ChangeState<TState>() where TState : FsmState<T>
        {
            ChangeState(typeof(TState));
        }

        /// <summary>
        /// 切换当前有限状态机状态。
        /// </summary>
        /// <param name="stateType">要切换到的有限状态机状态类型。</param>
        internal void ChangeState(Type stateType)
        {
            if (m_CurrentState == null)
            {
                throw new GameFrameworkException("Current state is invalid.");
            }

            FsmState<T> state = GetState(stateType);
            if (state == null)
            {
                throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not change state to '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), stateType.FullName));
            }

            m_CurrentState.OnLeave(this, false);
            m_CurrentStateTime = 0f;
            m_CurrentState = state;
            m_CurrentState.OnEnter(this);
        }
    }
}

View on GitHub (pinned to d0c010b051)