greenrobot/EventBus · error · EventBusException

This method may only be called from inside event handling me

Error message

This method may only be called from inside event handling methods on the posting thread

What it means

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.

Source

Thrown at EventBus/src/org/greenrobot/eventbus/EventBus.java:294

                }
            } finally {
                postingState.isPosting = false;
                postingState.isMainThread = false;
            }
        }
    }

    /**
     * Called from a subscriber's event handling method, further event delivery will be canceled. Subsequent
     * subscribers
     * won't receive the event. Events are usually canceled by higher priority subscribers (see
     * {@link Subscribe#priority()}). Canceling is restricted to event handling methods running in posting thread
     * {@link ThreadMode#POSTING}.
     */
    public void cancelEventDelivery(Object event) {
        PostingThreadState postingState = currentPostingThreadState.get();
        if (!postingState.isPosting) {
            throw new EventBusException(
                    "This method may only be called from inside event handling methods on the posting thread");
        } else if (event == null) {
            throw new EventBusException("Event may not be null");
        } else if (postingState.event != event) {
            throw new EventBusException("Only the currently handled event may be aborted");
        } else if (postingState.subscription.subscriberMethod.threadMode != ThreadMode.POSTING) {
            throw new EventBusException(" event handlers may only abort the incoming event");
        }

        postingState.canceled = true;
    }

    /**
     * Posts the given event to the event bus and holds on to the event (because it is sticky). The most recent sticky
     * event of an event's type is kept in memory for future access by subscribers using {@link Subscribe#sticky()}.
     */
    public void postSticky(Object event) {
        synchronized (stickyEvents) {

View on GitHub (pinned to 0194926b3b)

Solutions

  1. Move the cancelEventDelivery() call into a @Subscribe(threadMode = ThreadMode.POSTING) method so it executes on the posting thread during dispatch
  2. Give that subscriber a higher @Subscribe(priority = ...) than the subscribers you want to block, since cancellation only stops subsequent (lower-priority/later) subscribers
  3. If you need cross-thread cancellation semantics, redesign: don't post the event at all, or filter recipients instead of cancelling after the fact

Example fix

// before
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {
    EventBus.getDefault().cancelEventDelivery(event); // throws: not on posting thread
}

// after
@Subscribe(threadMode = ThreadMode.POSTING, priority = 100)
public void onEventPostingThread(MessageEvent event) {
    EventBus.getDefault().cancelEventDelivery(event); // ok: inside posting dispatch
}
Defensive patterns

Strategy: validation

Validate before calling

// Only cancel when actually inside a POSTING-mode dispatch of that event
@Subscribe(threadMode = ThreadMode.POSTING, priority = 100)
public void onEventPosting(MessageEvent event) {
    if (shouldSuppress(event)) {
        EventBus.getDefault().cancelEventDelivery(event);
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of greenrobot/EventBus@0194926b3b (2026-08-14). Data as JSON: /api/errors/9b78d698fa0b3c6e. Report an issue: GitHub.