{"record":{"id":"9b78d698fa0b3c6e","repo":"greenrobot/EventBus","slug":"this-method-may-only-be-called-from-inside-event-h","errorCode":null,"errorMessage":"This method may only be called from inside event handling methods on the posting thread","messagePattern":"This method may only be called from inside event handling methods on the posting thread","errorType":"exception","errorClass":"EventBusException","httpStatus":null,"severity":"error","filePath":"EventBus/src/org/greenrobot/eventbus/EventBus.java","lineNumber":294,"sourceCode":"                }\n            } finally {\n                postingState.isPosting = false;\n                postingState.isMainThread = false;\n            }\n        }\n    }\n\n    /**\n     * Called from a subscriber's event handling method, further event delivery will be canceled. Subsequent\n     * subscribers\n     * won't receive the event. Events are usually canceled by higher priority subscribers (see\n     * {@link Subscribe#priority()}). Canceling is restricted to event handling methods running in posting thread\n     * {@link ThreadMode#POSTING}.\n     */\n    public void cancelEventDelivery(Object event) {\n        PostingThreadState postingState = currentPostingThreadState.get();\n        if (!postingState.isPosting) {\n            throw new EventBusException(\n                    \"This method may only be called from inside event handling methods on the posting thread\");\n        } else if (event == null) {\n            throw new EventBusException(\"Event may not be null\");\n        } else if (postingState.event != event) {\n            throw new EventBusException(\"Only the currently handled event may be aborted\");\n        } else if (postingState.subscription.subscriberMethod.threadMode != ThreadMode.POSTING) {\n            throw new EventBusException(\" event handlers may only abort the incoming event\");\n        }\n\n        postingState.canceled = true;\n    }\n\n    /**\n     * Posts the given event to the event bus and holds on to the event (because it is sticky). The most recent sticky\n     * event of an event's type is kept in memory for future access by subscribers using {@link Subscribe#sticky()}.\n     */\n    public void postSticky(Object event) {\n        synchronized (stickyEvents) {","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/greenrobot/EventBus/blob/0194926b3bcf70cc0d7bfd3c5da16708dd5ab876/EventBus/src/org/greenrobot/eventbus/EventBus.java#L276-L312","documentation":"Thrown by cancelEventDelivery(Object) when the calling thread's ThreadLocal PostingThreadState has isPosting == false. Event cancellation works by setting a flag on the posting state that postSingleEventForEventType is iterating with; that state only exists while the current thread is actively dispatching an event. Calling cancelEventDelivery from any other context (a different thread, before/after event handling, or from a handler running in another ThreadMode's thread) has no state to cancel, so EventBus throws.","triggerScenarios":"Calling cancelEventDelivery(event) directly from application code, from a background thread, from a @Subscribe method whose threadMode is MAIN or BACKGROUND (those run on a different thread than the posting loop), or storing an event and trying to cancel it later.","commonSituations":"Developers trying to use cancelEventDelivery as a general 'revoke event' API; cancelling from inside a MAIN-mode subscriber while the event was posted from a background thread; unit tests calling cancellation outside a post() call.","solutions":["Move the cancelEventDelivery() call into a @Subscribe(threadMode = ThreadMode.POSTING) method so it executes on the posting thread during dispatch","Give that subscriber a higher @Subscribe(priority = ...) than the subscribers you want to block, since cancellation only stops subsequent (lower-priority/later) subscribers","If you need cross-thread cancellation semantics, redesign: don't post the event at all, or filter recipients instead of cancelling after the fact"],"exampleFix":"// before\n@Subscribe(threadMode = ThreadMode.MAIN)\npublic void onEvent(MessageEvent event) {\n    EventBus.getDefault().cancelEventDelivery(event); // throws: not on posting thread\n}\n\n// after\n@Subscribe(threadMode = ThreadMode.POSTING, priority = 100)\npublic void onEventPostingThread(MessageEvent event) {\n    EventBus.getDefault().cancelEventDelivery(event); // ok: inside posting dispatch\n}","handlingStrategy":"validation","validationCode":"// Only cancel when actually inside a POSTING-mode dispatch of that event\n@Subscribe(threadMode = ThreadMode.POSTING, priority = 100)\npublic void onEventPosting(MessageEvent event) {\n    if (shouldSuppress(event)) {\n        EventBus.getDefault().cancelEventDelivery(event);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call cancelEventDelivery only from @Subscribe(threadMode = ThreadMode.POSTING) methods","Give cancelling subscribers a higher priority than those they preempt","Treat cancelEventDelivery as dispatch-scoped, never as a general API"],"tags":["eventbus","cancellation","threading","threadmode"],"backgroundTag":null,"analyzedSha":"0194926b3bcf70cc0d7bfd3c5da16708dd5ab876","analyzedAt":"2026-08-14T10:41:08.786Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}