{"record":{"id":"13ebada39be933b4","repo":"greenrobot/EventBus","slug":"subscriber-subscriber-getclass-already-regist","errorCode":null,"errorMessage":"Subscriber ${subscriber.getClass()} already registered to event ${eventType}","messagePattern":"Subscriber (.+?) already registered to event (.+?)","errorType":"exception","errorClass":"EventBusException","httpStatus":null,"severity":"error","filePath":"EventBus/src/org/greenrobot/eventbus/EventBus.java","lineNumber":168,"sourceCode":"        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);\n        synchronized (this) {\n            for (SubscriberMethod subscriberMethod : subscriberMethods) {\n                subscribe(subscriber, subscriberMethod);\n            }\n        }\n    }\n\n    // Must be called in synchronized block\n    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {\n        Class<?> eventType = subscriberMethod.eventType;\n        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);\n        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);\n        if (subscriptions == null) {\n            subscriptions = new CopyOnWriteArrayList<>();\n            subscriptionsByEventType.put(eventType, subscriptions);\n        } else {\n            if (subscriptions.contains(newSubscription)) {\n                throw new EventBusException(\"Subscriber \" + subscriber.getClass() + \" already registered to event \"\n                        + eventType);\n            }\n        }\n\n        int size = subscriptions.size();\n        for (int i = 0; i <= size; i++) {\n            if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {\n                subscriptions.add(i, newSubscription);\n                break;\n            }\n        }\n\n        List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);\n        if (subscribedEvents == null) {\n            subscribedEvents = new ArrayList<>();\n            typesBySubscriber.put(subscriber, subscribedEvents);\n        }\n        subscribedEvents.add(eventType);","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/greenrobot/EventBus/blob/0194926b3bcf70cc0d7bfd3c5da16708dd5ab876/EventBus/src/org/greenrobot/eventbus/EventBus.java#L150-L186","documentation":"Thrown from the private subscribe() method (called inside a synchronized block from register()) when the per-event-type subscription list already contains an equal Subscription for this subscriber. EventBus refuses double registration of the same subscriber instance for the same event type because each register() would otherwise deliver each event twice to the same method. Subscription equality is subscriber instance + subscriber method, so this fires on a redundant register() call for the same object.","triggerScenarios":"Calling register(this) twice on the same subscriber instance without an intervening unregister(this) — e.g. register in both onCreate() and onResume() of an Android Activity; re-registering a cached singleton presenter; calling register() again after a configuration change where the same instance survived.","commonSituations":"Android lifecycle overlap (onCreate + onStart both registering), retained fragments or presenters registered repeatedly, defensive 'make sure I'm registered' register() calls in loops, or a register() added in a base class plus another in the subclass.","solutions":["Call unregister(this) in the matching lifecycle teardown (e.g. onPause()/onDestroy()) for every register(this) in onCreate()/onResume()","Guard registration with EventBus.getDefault().isRegistered(this) before calling register()","Remove the duplicate register() call (search for all register( invocations for the class named in the message)","Keep registration in exactly one lifecycle callback pair per component"],"exampleFix":"// before\n@Override\nprotected void onResume() {\n    super.onResume();\n    EventBus.getDefault().register(this); // called again -> already registered\n}\n\n// after\n@Override\nprotected void onResume() {\n    super.onResume();\n    if (!EventBus.getDefault().isRegistered(this)) {\n        EventBus.getDefault().register(this);\n    }\n}","handlingStrategy":"validation","validationCode":"EventBus bus = EventBus.getDefault();\nif (!bus.isRegistered(this)) {\n    bus.register(this);\n}","typeGuard":null,"tryCatchPattern":"try {\n    EventBus.getDefault().register(this);\n} catch (EventBusException e) {\n    if (String.valueOf(e.getMessage()).contains(\"already registered\")) {\n        EventBus.getDefault().unregister(this);\n        EventBus.getDefault().register(this);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Pair every register() with an unregister() in the mirrored lifecycle callback","Wrap registration in a single helper that checks isRegistered() first","Register in exactly one place per component (e.g. base class only)"],"tags":["eventbus","lifecycle","double-registration","android"],"backgroundTag":null,"analyzedSha":"0194926b3bcf70cc0d7bfd3c5da16708dd5ab876","analyzedAt":"2026-08-14T10:41:08.786Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}