{"record":{"id":"07d7776111f41d4f","repo":"owasp-amass/amass","slug":"handler-at-position-d-already-registered-for-even","errorCode":null,"errorMessage":"handler at position %d already registered for EventType %s","messagePattern":"handler at position (.+?) already registered for EventType (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/registry/registry.go","lineNumber":69,"sourceCode":"\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}\n\n\tr.handlers[atype][p] = append(r.handlers[atype][p], h)\n\treturn nil\n}\n","sourceCodeStart":51,"sourceCodeEnd":78,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/registry/registry.go#L51-L78","documentation":"Registry.RegisterHandler rejects a handler with Exclusive=true whose (EventType, Position) slot already holds at least one handler. Exclusive handlers claim a position on an event type; the engine clamps Position to [1,50] and errors if the slot is taken, logging the failure and returning the error.","triggerScenarios":"Calling RegisterHandler with h.Exclusive=true and h.Position = N where r.handlers[EventType][N] already contains handlers — e.g. two exclusive handlers both claiming position 2 for oam.Netblock, or a built-in plugin already occupying the slot your custom handler requests.","commonSituations":"Custom plugin registering at the same position as a built-in plugin's exclusive handler; two copies of the same plugin both claiming an exclusive slot; changing a plugin to Exclusive while another handler occupies its position; misconfigured Position values colliding across plugins.","solutions":["Choose a different (free) Position for the exclusive handler","Set Exclusive=false if sharing the position with other handlers is acceptable","Inventory existing registered handlers per EventType/Position before assigning positions","Ensure plugins are not started twice, which would collide with their own exclusive slot"],"exampleFix":"// before\n&et.Handler{Name: \"asn\", EventType: oam.Netblock, Position: 2, Exclusive: true} // slot 2 taken\n// after\n&et.Handler{Name: \"asn\", EventType: oam.Netblock, Position: 3, Exclusive: true} // free slot","handlingStrategy":"validation","validationCode":"// before registering an exclusive handler, reserve/free the slot\nconst maxPos = 50\nfunc positionFree(reg *registry.Registry, eventType string, pos int) bool {\n    if pos < 1 || pos > maxPos { return false }\n    return len(reg.HandlersAt(eventType, pos)) == 0\n}","typeGuard":null,"tryCatchPattern":"if err := registry.RegisterHandler(h); err != nil {\n    if strings.Contains(err.Error(), \"already registered\") {\n        h.Position++ // or set Exclusive=false and retry once\n        return registry.RegisterHandler(h)\n    }\n    return err\n}","preventionTips":["Document and allocate positions across all plugins to avoid collisions","Only mark handlers Exclusive when they truly must own a position","Keep Position within 1..50 (the registry clamps, but out-of-range invites conflicts)","Check whether a built-in plugin already claims the position before choosing it"],"tags":["registry","plugin","handler","position-conflict","exclusive"],"backgroundTag":"conflicting-config-options","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"}