EllanJiang/GameFramework · error · GameFrameworkException

Event ' ' not allow duplicate handler.

Error message

Event '{0}' not allow duplicate handler.

What it means

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.

Solutions

  1. Add EventPoolMode.AllowDuplicateHandler to the pool mode only if duplicate invocation is truly intended (rare).
  2. Call Unsubscribe(id, handler) before Subscribe, or guard with if (!eventPool.Check(id, handler)) Subscribe(...).
  3. Balance lifecycle: subscribe in OnEnable, unsubscribe in OnDisable.
  4. Keep one canonical delegate instance (store the method group in a field) so Check-based guards work reliably.

Example fix

// before
eventComponent.Subscribe((int)GameEvent.Update, OnUpdate); // called every OnEnable
// after
if (!eventComponent.Check((int)GameEvent.Update, OnUpdate))
{
    eventComponent.Subscribe((int)GameEvent.Update, OnUpdate);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!eventPool.Check(id, handler))
{
    eventPool.Subscribe(id, handler);
}

Try / catch

try
{
    eventPool.Subscribe(id, handler);
}
catch (GameFrameworkException ex) when (ex.Message.Contains("not allow duplicate handler"))
{
    // handler already registered — safe to ignore or log at debug level
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15). Data as JSON: /api/errors/c4843049f777a1a3. Report an issue: GitHub.

Appendix: source

Thrown at GameFramework/Base/EventPool/EventPool.cs:157

        /// <param name="handler">要订阅的事件处理函数。</param>
        public void Subscribe(int id, EventHandler<T> handler)
        {
            if (handler == null)
            {
                throw new GameFrameworkException("Event handler is invalid.");
            }

            if (!m_EventHandlers.Contains(id))
            {
                m_EventHandlers.Add(id, handler);
            }
            else if ((m_EventPoolMode & EventPoolMode.AllowMultiHandler) != EventPoolMode.AllowMultiHandler)
            {
                throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow multi handler.", id));
            }
            else if ((m_EventPoolMode & EventPoolMode.AllowDuplicateHandler) != EventPoolMode.AllowDuplicateHandler && Check(id, handler))
            {
                throw new GameFrameworkException(Utility.Text.Format("Event '{0}' not allow duplicate handler.", id));
            }
            else
            {
                m_EventHandlers.Add(id, handler);
            }
        }

        /// <summary>
        /// 取消订阅事件处理函数。
        /// </summary>
        /// <param name="id">事件类型编号。</param>
        /// <param name="handler">要取消订阅的事件处理函数。</param>
        public void Unsubscribe(int id, EventHandler<T> handler)
        {
            if (handler == null)
            {
                throw new GameFrameworkException("Event handler is invalid.");
            }

View on GitHub (pinned to d0c010b051)