{"record":{"id":"1b002ec91243744d","repo":"EllanJiang/GameFramework","slug":"current-state-is-invalid","errorCode":null,"errorMessage":"Current state is invalid.","messagePattern":"Current state is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Fsm/Fsm.cs","lineNumber":573,"sourceCode":"\n        /// <summary>\n        /// 切换当前有限状态机状态。\n        /// </summary>\n        /// <typeparam name=\"TState\">要切换到的有限状态机状态类型。</typeparam>\n        internal void ChangeState<TState>() where TState : FsmState<T>\n        {\n            ChangeState(typeof(TState));\n        }\n\n        /// <summary>\n        /// 切换当前有限状态机状态。\n        /// </summary>\n        /// <param name=\"stateType\">要切换到的有限状态机状态类型。</param>\n        internal void ChangeState(Type stateType)\n        {\n            if (m_CurrentState == null)\n            {\n                throw new GameFrameworkException(\"Current state is invalid.\");\n            }\n\n            FsmState<T> state = GetState(stateType);\n            if (state == null)\n            {\n                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));\n            }\n\n            m_CurrentState.OnLeave(this, false);\n            m_CurrentStateTime = 0f;\n            m_CurrentState = state;\n            m_CurrentState.OnEnter(this);\n        }\n    }\n}\n","sourceCodeStart":555,"sourceCodeEnd":589,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Fsm/Fsm.cs#L555-L589","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the FSM was created with a valid start state and has entered it before changing state","Only call ChangeState from within state OnUpdate/OnLeave flows or after the FSM is running","Check FSM lifetime management so Shutdown does not race with ChangeState calls","Verify CreateFsm was given a states array containing the intended start state"],"exampleFix":"// before\nfsm.ChangeState(typeof(MoveState)); // may run before FSM started\n// after\nif (fsm.CurrentState != null)\n{\n    fsm.ChangeState(typeof(MoveState));\n}","handlingStrategy":"validation","validationCode":"if (fsm == null || fsm.CurrentState == null) throw new InvalidOperationException(\"FSM not started\");","typeGuard":"bool CanChangeState(Fsm<T> fsm) => fsm != null && fsm.CurrentState != null;","tryCatchPattern":"try { fsm.ChangeState(typeof(TargetState)); } catch (GameFrameworkException ex) when (ex.Message == \"Current state is invalid.\") { /* FSM not running: re-init or queue transition */ }","preventionTips":["Change states only from within state lifecycle methods (OnEnter/OnUpdate/OnLeave)","Ensure the FSM is created with a valid start state and polled before external transitions","Coordinate Shutdown with transition requests to avoid lifecycle races"],"tags":["fsm","state-machine","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}