{"record":{"id":"7984cd67b4c91e5a","repo":"EllanJiang/GameFramework","slug":"fsm-is-invalid","errorCode":null,"errorMessage":"FSM is invalid.","messagePattern":"FSM is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Fsm/FsmManager.cs","lineNumber":362,"sourceCode":"            if (ownerType == null)\n            {\n                throw new GameFrameworkException(\"Owner type is invalid.\");\n            }\n\n            return InternalDestroyFsm(new TypeNamePair(ownerType, name));\n        }\n\n        /// <summary>\n        /// 销毁有限状态机。\n        /// </summary>\n        /// <typeparam name=\"T\">有限状态机持有者类型。</typeparam>\n        /// <param name=\"fsm\">要销毁的有限状态机。</param>\n        /// <returns>是否销毁有限状态机成功。</returns>\n        public bool DestroyFsm<T>(IFsm<T> fsm) where T : class\n        {\n            if (fsm == null)\n            {\n                throw new GameFrameworkException(\"FSM is invalid.\");\n            }\n\n            return InternalDestroyFsm(new TypeNamePair(typeof(T), fsm.Name));\n        }\n\n        /// <summary>\n        /// 销毁有限状态机。\n        /// </summary>\n        /// <param name=\"fsm\">要销毁的有限状态机。</param>\n        /// <returns>是否销毁有限状态机成功。</returns>\n        public bool DestroyFsm(FsmBase fsm)\n        {\n            if (fsm == null)\n            {\n                throw new GameFrameworkException(\"FSM is invalid.\");\n            }\n\n            return InternalDestroyFsm(new TypeNamePair(fsm.OwnerType, fsm.Name));","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Fsm/FsmManager.cs#L344-L380","documentation":"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.","triggerScenarios":"Calling DestroyFsm<T>(null) — null interface reference passed as the argument.","commonSituations":"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.","solutions":["Null-check the IFsm reference before calling DestroyFsm","Keep a valid reference from CreateFsm/GetFsm and avoid nulling it before destruction","Call HasFsm<T>(name) first to confirm the FSM still exists and re-fetch it"],"exampleFix":"// before\nif (m_Fsm == null) m_Fsm = fsmManager.GetFsm<Player>(\"movement\");\nfsmManager.DestroyFsm(m_Fsm); // still throws if null\n// after\nif (m_Fsm != null)\n{\n    fsmManager.DestroyFsm(m_Fsm);\n    m_Fsm = null;\n}","handlingStrategy":"validation","validationCode":"if (fsm != null)\n    fsmManager.DestroyFsm(fsm);","typeGuard":"static bool IsDestroyable<T>(IFsm<T> fsm) where T : class => fsm != null;","tryCatchPattern":"try { fsmManager.DestroyFsm(movementFsm); }\ncatch (GameFrameworkException ex) { Log.Error(\"DestroyFsm failed: {0}\", ex.Message); }\nfinally { movementFsm = null; }","preventionTips":["Assign IFsm fields immediately from CreateFsm/GetFsm","Null fields when destroyed and re-check before use","Centralize FSM create/destroy in one manager class"],"tags":["csharp","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"}