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
- Create the event pool with EventPoolMode.AllowMultiHandler if multiple handlers per event are intended.
- Unsubscribe the previous handler before subscribing again for the same id.
- Make sure each event id is unique — rename colliding enum constants.
- 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
- Decide the multi-handler policy once when constructing the EventPool and document it.
- Use unique event-id enum values per event; audit for duplicate ids.
- Always pair Subscribe with Unsubscribe in enable/disable lifecycle methods.
- Use Check(id, handler) before subscribing to detect existing handlers.
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
- Event ' ' not allow duplicate handler.
- Event handler is invalid.
- Event ' ' not exists specified handler.
- Event is invalid.
- Event ' ' not allow no handler.
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)