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
- 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.
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
- 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.
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
- Event ' ' not allow multi 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/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)