{"record":{"id":"fc65c55abb5c2955","repo":"owasp-amass/amass","slug":"handler-s-already-registered-for-eventtype-s","errorCode":null,"errorMessage":"handler %s already registered for EventType %s","messagePattern":"handler (.+?) already registered for EventType (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/registry/registry.go","lineNumber":55,"sourceCode":"\tdefer r.Unlock()\n\n\t// is the entry for the requested event type currently empty?\n\tif _, found := r.handlers[h.EventType]; !found {\n\t\tr.handlers[h.EventType] = make(map[int][]*et.Handler)\n\t}\n\t// has this registration been made already?\n\tvar found bool\nloop:\n\tfor _, handlers := range r.handlers[h.EventType] {\n\t\tfor _, handler := range handlers {\n\t\t\tif handler.Name == h.Name {\n\t\t\t\tfound = true\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t}\n\t}\n\tif found {\n\t\terr := fmt.Errorf(\"handler %s already registered for EventType %s\", h.Name, h.EventType)\n\t\tr.Log().Error(fmt.Sprintf(\"Failed to register a handler: %v\", err),\n\t\t\tslog.Group(\"plugin\", \"name\", h.Plugin.Name(), \"handler\", h.Name))\n\t\treturn err\n\t}\n\n\tif h.Position <= 0 {\n\t\th.Position = 1\n\t} else if h.Position > 50 {\n\t\th.Position = 50\n\t}\n\n\tatype, p := h.EventType, h.Position\n\tif handlers, found := r.handlers[atype][p]; found && len(handlers) > 0 && h.Exclusive {\n\t\terr := fmt.Errorf(\"handler at position %d already registered for EventType %s\", p, atype)\n\t\tr.Log().Error(fmt.Sprintf(\"Failed to register a handler: %v\", err),\n\t\t\tslog.Group(\"plugin\", \"name\", h.Plugin.Name(), \"handler\", h.Name))\n\t\treturn err\n\t}","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/registry/registry.go#L37-L73","documentation":"Registry.RegisterHandler rejects a handler whose (Name, EventType) pair is already registered. The engine forbids duplicate named handlers for the same event type to keep event-dispatch deterministic; it logs the failure via the registry logger and returns the error to the caller (the plugin's Start/OnStart).","triggerScenarios":"Calling RegisterHandler (directly or via a plugin's Start) with a Handler whose Name and EventType match an already-registered handler — e.g. starting the same plugin twice, or two handlers sharing a name for the same EventType.","commonSituations":"Calling engine.Start()/plugin Start() twice without stopping; registering the same handler instance again after a failed start partially succeeded; two custom plugins accidentally using the same handler name for the same event type; hot-reload code re-registering handlers.","solutions":["Check whether the plugin/engine was already started and skip or stop it before re-registering","Ensure each Handler has a unique Name per EventType across all plugins","Call Stop/unregister for existing handlers before re-registering in reload logic","Call RegisterHandler only once per handler instance during initialization"],"exampleFix":"// before\nif err := engine.Start(); err != nil { ... } // plugin re-registered on restart\n// after\nif err := engine.Stop(); err != nil { ... }\nif err := engine.Start(); err != nil { ... } // unregister before re-register","handlingStrategy":"try-catch","validationCode":"// check before registering (pseudo-API)\nif registry.IsRegistered(handler.Name, handler.EventType) {\n    return fmt.Errorf(\"handler %s for %s already registered\", handler.Name, handler.EventType)\n}\n// also guard against double-start\nif engine.IsRunning() { return nil }","typeGuard":null,"tryCatchPattern":"if err := engine.Start(); err != nil {\n    if strings.Contains(err.Error(), \"already registered\") {\n        // skip re-registration or stop & restart engine first\n    } else {\n        return err\n    }\n}","preventionTips":["Start the engine/plugins exactly once per process lifetime","Give every handler a unique Name per EventType","In reload logic, stop/unregister existing handlers before re-registering","Check the wrapped error message for 'already registered' to distinguish from startup failures"],"tags":["registry","plugin","duplicate-handler","registration"],"backgroundTag":"file-already-exists","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}