{"record":{"id":"c4843049f777a1a3","repo":"EllanJiang/GameFramework","slug":"event-0-not-allow-duplicate-handler","errorCode":null,"errorMessage":"Event '{0}' not allow duplicate handler.","messagePattern":"Event '(.+?)' not allow duplicate handler\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/EventPool/EventPool.cs","lineNumber":157,"sourceCode":"        /// <param name=\"handler\">要订阅的事件处理函数。</param>\n        public void Subscribe(int id, EventHandler<T> handler)\n        {\n            if (handler == null)\n            {\n                throw new GameFrameworkException(\"Event handler is invalid.\");\n            }\n\n            if (!m_EventHandlers.Contains(id))\n            {\n                m_EventHandlers.Add(id, handler);\n            }\n            else if ((m_EventPoolMode & EventPoolMode.AllowMultiHandler) != EventPoolMode.AllowMultiHandler)\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"Event '{0}' not allow multi handler.\", id));\n            }\n            else if ((m_EventPoolMode & EventPoolMode.AllowDuplicateHandler) != EventPoolMode.AllowDuplicateHandler && Check(id, handler))\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"Event '{0}' not allow duplicate handler.\", id));\n            }\n            else\n            {\n                m_EventHandlers.Add(id, handler);\n            }\n        }\n\n        /// <summary>\n        /// 取消订阅事件处理函数。\n        /// </summary>\n        /// <param name=\"id\">事件类型编号。</param>\n        /// <param name=\"handler\">要取消订阅的事件处理函数。</param>\n        public void Unsubscribe(int id, EventHandler<T> handler)\n        {\n            if (handler == null)\n            {\n                throw new GameFrameworkException(\"Event handler is invalid.\");\n            }","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/EventPool/EventPool.cs#L139-L175","documentation":"Subscribe throws this when AllowDuplicateHandler is not part of the pool's EventPoolMode and the exact same handler delegate is already registered for the event id (detected via Check(id, handler)). The pool deliberately prevents registering the identical delegate twice so it would fire twice per event. Note this check only runs when AllowMultiHandler is already enabled; without it, error 27 fires first.","triggerScenarios":"With EventPoolMode.AllowMultiHandler (but not AllowDuplicateHandler), calling Subscribe(id, sameHandler) a second time — e.g. re-subscribing in OnEnable without unsubscribing in OnDisable, or subscribing from two places that both reference the same method group/delegate field.","commonSituations":"Unity lifecycle bugs (Subscribe in OnEnable/Awake without matching Unsubscribe); scene reload re-running subscription code against a persistent pool; multiple components sharing a static handler delegate.","solutions":["Add EventPoolMode.AllowDuplicateHandler to the pool mode only if duplicate invocation is truly intended (rare).","Call Unsubscribe(id, handler) before Subscribe, or guard with if (!eventPool.Check(id, handler)) Subscribe(...).","Balance lifecycle: subscribe in OnEnable, unsubscribe in OnDisable.","Keep one canonical delegate instance (store the method group in a field) so Check-based guards work reliably."],"exampleFix":"// before\neventComponent.Subscribe((int)GameEvent.Update, OnUpdate); // called every OnEnable\n// after\nif (!eventComponent.Check((int)GameEvent.Update, OnUpdate))\n{\n    eventComponent.Subscribe((int)GameEvent.Update, OnUpdate);\n}","handlingStrategy":"validation","validationCode":"if (!eventPool.Check(id, handler))\n{\n    eventPool.Subscribe(id, handler);\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    eventPool.Subscribe(id, handler);\n}\ncatch (GameFrameworkException ex) when (ex.Message.Contains(\"not allow duplicate handler\"))\n{\n    // handler already registered — safe to ignore or log at debug level\n}","preventionTips":["Store handlers in fields and use Check-then-Subscribe guards for idempotent subscription.","Balance OnEnable/OnDisable (or Awake/OnDestroy) subscribe/unsubscribe pairs.","Avoid subscribing the same static method from multiple call sites.","Enable AllowDuplicateHandler only when repeated invocation is explicitly required."],"tags":["event-pool","eventpoolmode","duplicate-handler"],"backgroundTag":"conflicting-config-options","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"}