{"record":{"id":"577fd9c753246af9","repo":"EllanJiang/GameFramework","slug":"state-type-is-invalid","errorCode":null,"errorMessage":"State type is invalid.","messagePattern":"State type is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Fsm/Fsm.cs","lineNumber":287,"sourceCode":"            m_CurrentStateTime = 0f;\n            m_CurrentState = state;\n            m_CurrentState.OnEnter(this);\n        }\n\n        /// <summary>\n        /// 开始有限状态机。\n        /// </summary>\n        /// <param name=\"stateType\">要开始的有限状态机状态类型。</param>\n        public void Start(Type stateType)\n        {\n            if (IsRunning)\n            {\n                throw new GameFrameworkException(\"FSM is running, can not start again.\");\n            }\n\n            if (stateType == null)\n            {\n                throw new GameFrameworkException(\"State type is invalid.\");\n            }\n\n            if (!typeof(FsmState<T>).IsAssignableFrom(stateType))\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"State type '{0}' is invalid.\", stateType.FullName));\n            }\n\n            FsmState<T> state = GetState(stateType);\n            if (state == null)\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"FSM '{0}' can not start state '{1}' which is not exist.\", new TypeNamePair(typeof(T), Name), stateType.FullName));\n            }\n\n            m_CurrentStateTime = 0f;\n            m_CurrentState = state;\n            m_CurrentState.OnEnter(this);\n        }\n","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Fsm/Fsm.cs#L269-L305","documentation":"Guard in Fsm<T>.Start(Type): thrown when stateType is null. Starting the state machine requires an initial state type to look up among the registered states; a null type cannot be resolved, so the FSM refuses to start rather than entering an invalid state.","triggerScenarios":"Calling fsm.Start(someType) where someType is null, typically from a Type variable filled by typeof on a null source, reflection that failed to resolve the type, or serialized/type-reference data that was never assigned.","commonSituations":"Config-driven FSM startup where the initial state type string failed to resolve to a Type; ScriptableObject/Inspector fields of System.Type left unset; reflection by name with a typo or a type stripped by IL2CPP.","solutions":["Ensure the Type value is resolved (typeof(TState) or Type.GetType with a valid assembly-qualified name) before calling Start","Use the generic Start<TState>() overload, which cannot receive null","Validate the field/config value at load time and fail early"],"exampleFix":"// before\nType startState = Type.GetType(stateTypeName);\nfsm.Start(startState); // null if name wrong\n// after\nType startState = Type.GetType(stateTypeName) ?? typeof(IdleState);\nif (startState != null) fsm.Start(startState);","handlingStrategy":"validation","validationCode":"if (stateType == null)\n    throw new ArgumentException(\"Start state type must be resolved before calling Start\");\nfsm.Start(stateType);","typeGuard":"bool IsValidStateType(Type t) => t != null && typeof(FsmState<T>).IsAssignableFrom(t);","tryCatchPattern":"try { fsm.Start(stateType); }\ncatch (GameFrameworkException ex) { Log.Error(\"Invalid start state type: {0}\", ex.Message); }","preventionTips":["Prefer the generic Start<TState>() overload","Validate serialized/config type names at load time","Use assembly-qualified names with Type.GetType and log resolution failures"],"tags":["unity","fsm","null-argument"],"backgroundTag":"null-argument","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}