EllanJiang/GameFramework · error · GameFrameworkException
FSM is running, can not start again.
Error message
FSM is running, can not start again.
What it means
Fsm<T>.Start<TState>() transitions the FSM into its initial state. A state machine may only be started once; if IsRunning is already true, the guard at Fsm.cs:260 throws this exception instead of silently restarting the machine.
Solutions
- Call Start<TState>() only once per FSM lifetime; guard subsequent calls with if (!fsm.IsRunning) fsm.Start<TState>();
- If a restart is intended, destroy/shutdown the existing FSM (return it to ReferencePool via the FsmComponent) and recreate it before starting.
- Move the Start call out of OnEnable into a one-time initialization path (e.g. Start() or an explicit Init method).
Example fix
// before
void OnEnable()
{
m_Fsm.Start<IdleState>(); // throws if already running
}
// after
void OnEnable()
{
if (m_Fsm != null && !m_Fsm.IsRunning)
{
m_Fsm.Start<IdleState>();
}
} Defensive patterns
Strategy: type-guard
Validate before calling
if (m_Fsm == null || m_Fsm.IsDestroyed) { RecreateFsm(); }
if (!m_Fsm.IsRunning) { m_Fsm.Start<IdleState>(); } Type guard
bool CanStart(Fsm<MyComponent> fsm) => fsm != null && !fsm.IsRunning;
Try / catch
try { m_Fsm.Start<IdleState>(); }
catch (GameFrameworkException ex) { Log.Warning("FSM already started: " + ex.Message); } Prevention
- Call Start<TState>() exactly once, from a one-time init path — not OnEnable, which can run repeatedly.
- Check IsRunning before any Start call in shared or re-entrant code paths.
- To restart, destroy and recreate the FSM through the FsmComponent instead of calling Start again.
When it happens
Trigger: Calling Start<TState>() twice on the same Fsm<T> instance — e.g. Start in both an init method and OnEnable, or Start called again after ChangeState/use without creating a fresh FSM.
Common situations: Unity components whose OnEnable runs multiple times (disable/enable cycles) re-calling Start; re-initializing gameplay logic without destroying and recreating the FSM via the FsmComponent; two systems each attempting to start a shared FSM.
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
- FSM owner is invalid.
- FSM states is invalid.
- FSM ' ' state ' ' is already exist.
- Results is invalid.
- Already exist FSM ' '.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/bd77f618fa2cc6d5.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/Fsm/Fsm.cs:260
}
m_Datas.Clear();
}
m_CurrentState = null;
m_CurrentStateTime = 0f;
m_IsDestroyed = true;
}
/// <summary>
/// 开始有限状态机。
/// </summary>
/// <typeparam name="TState">要开始的有限状态机状态类型。</typeparam>
public void Start<TState>() where TState : FsmState<T>
{
if (IsRunning)
{
throw new GameFrameworkException("FSM is running, can not start again.");
}
FsmState<T> state = GetState<TState>();
if (state == null)
{
throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not start state '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), typeof(TState).FullName));
}
m_CurrentStateTime = 0f;
m_CurrentState = state;
m_CurrentState.OnEnter(this);
}
/// <summary>
/// 开始有限状态机。
/// </summary>
/// <param name="stateType">要开始的有限状态机状态类型。</param>
public void Start(Type stateType)View on GitHub (pinned to d0c010b051)