EllanJiang/GameFramework · error · GameFrameworkException

Event ' ' not allow multi handler.

Error message

Event '{0}' not allow multi handler.

What it means

Subscribe throws this when the pool's EventPoolMode does not include AllowMultiHandler but a second handler is being registered for an event id that already has one. GameFramework's event pool intentionally restricts each event id to a single handler unless AllowMultiHandler is enabled at pool construction, to catch accidental overwrite-style subscription bugs.

Solutions

  1. Create the event pool with EventPoolMode.AllowMultiHandler if multiple handlers per event are intended.
  2. Unsubscribe the previous handler before subscribing again for the same id.
  3. Make sure each event id is unique — rename colliding enum constants.
  4. Track subscription state (bool flag) so Subscribe is only called once per handler/id.

Example fix

// before
m_EventPool = new EventPool<GameEventEventArgs>(EventPoolMode.Default);
m_EventPool.Subscribe(id, handler1);
m_EventPool.Subscribe(id, handler2); // throws
// after
m_EventPool = new EventPool<GameEventEventArgs>(EventPoolMode.AllowMultiHandler);
m_EventPool.Subscribe(id, handler1);
m_EventPool.Subscribe(id, handler2);
Defensive patterns

Strategy: validation

Validate before calling

if (eventPool.Check(id, handler) || HasAnyHandler(id))
{
    // already handled — skip or Unsubscribe first
}
else
{
    eventPool.Subscribe(id, handler);
}
// or verify pool mode at startup:
Debug.Assert((poolMode & EventPoolMode.AllowMultiHandler) != 0 || FirstSubscribe);

Try / catch

try
{
    eventPool.Subscribe(id, handler);
}
catch (GameFrameworkException ex) when (ex.Message.Contains("not allow multi handler"))
{
    eventPool.Unsubscribe(id, existingHandler);
    eventPool.Subscribe(id, handler);
}

Prevention

When it happens

Trigger: Calling Subscribe(id, handler) twice for the same id on a pool created with EventPoolMode.Default (or any mode without AllowMultiHandler); two different systems independently subscribing to the same custom event id; re-subscribing in OnEnable without unsubscribing in OnDisable.

Common situations: Duplicate event id constants defined in an enum; a UI panel that subscribes in OnEnable but forgets Unsubscribe in OnDisable, then re-subscribes on reopen; two game modules choosing the same int id for different events.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

        /// <summary>
        /// 订阅事件处理函数。
        /// </summary>
        /// <param name="id">事件类型编号。</param>
        /// <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)
        {

View on GitHub (pinned to d0c010b051)