Unity-Technologies/UnityCsReference · error · Exception

Delegate already registered for dropDestinationId:{dropDstId

Error message

Delegate already registered for dropDestinationId:{dropDstId}

What it means

Thrown by DragAndDrop.AddDropHandler when the exact (dropDstId, handler) pair is already registered. HasHandler checks identity equality (dropHandler == handler), so registering the same delegate instance for the same destination twice is the trigger — distinct lambdas capturing the same target are treated as different. This is a registration-correctness guard against duplicate invocations during a drop.

Source

Thrown at Editor/Mono/DragAndDrop.bindings.cs:91

                    AddDropHandlerV2(DefaultProjectBrowserDropHandler);
                    AddDropHandlerV2(DefaultInspectorDropHandler);
                    AddDropHandlerV2(DefaultHierarchyDropHandler);
                }
                return m_DropHandlers;
            }
        }

        internal static void ClearDropHandlers()
        {
            m_DropHandlers?.Clear();
            m_DropHandlers = null;
        }

        internal static void AddDropHandler(int dropDstId, Delegate handler)
        {
            if (HasHandler(dropDstId, handler))
            {
                throw new Exception("Delegate already registered for dropDestinationId:" + dropDstId);
            }

            if (!dropHandlers.TryGetValue(dropDstId, out var handlers))
            {
                handlers = new List<Delegate>();
                dropHandlers[dropDstId] = handlers;
            }
            handlers.Add(handler);
        }

        internal static void RemoveDropHandler(int dropDstId, Delegate handler)
        {
            if (dropHandlers.TryGetValue(dropDstId, out var handlers))
            {
                handlers.RemoveAll(dropHandler => dropHandler == handler);
            }
        }

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Always pair AddDropHandler in OnEnable with RemoveDropHandler in OnDisable using the same cached delegate instance.
  2. Cache the handler delegate in a field so the same instance is added and removed; do not pass a fresh lambda each time.
  3. Before adding, call DragAndDrop.HasHandler(dropDstId, handler) and skip if already present.

Example fix

// before
void OnEnable() { DragAndDrop.AddDropHandler(kId, HandleDrop); }
void OnDisable() { /* forgot to remove */ }
// after
static readonly DragAndDrop.HierarchyDropHandler s_Handler = HandleDrop;
void OnEnable()  { DragAndDrop.AddDropHandler(kId, s_Handler); }
void OnDisable() { DragAndDrop.RemoveDropHandler(kId, s_Handler); }
Defensive patterns

Strategy: validation

Validate before calling

if (DragAndDrop.HasHandler(dropDstId, cachedHandler)) return;
DragAndDrop.AddDropHandler(dropDstId, cachedHandler);

Prevention

When it happens

Trigger: Calling DragAndDrop.AddDropHandler with the same delegate instance and same dropDstId more than once without an intervening RemoveDropHandler. Commonly when a window/editor enables its handlers in OnEnable and OnEnable runs twice (e.g. after a domain reload or re-selection) without a matching OnDisable cleanup.

Common situations: An EditorWindow that registers a static or cached delegate in OnEnable and is re-enabled (recompile, play-mode toggle) without unregistering; a package that registers on every assembly load.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/072cbc57285de3d4. Report an issue: GitHub.