apache/dolphinscheduler · error · RuntimeException
"The object being compared is not a TaskReadyForDispatchEven
Error message
"The object being compared is not a TaskReadyForDispatchEvent."
What it means
TaskDispatchableEvent implements Delayed and its compareTo assumes every other element in the delay queue is also a TaskDispatchableEvent. If compareTo is handed a different Delayed implementation (e.g. another kind of retry/scheduled event sharing the same DelayQueue), it throws RuntimeException with this legacy 'TaskReadyForDispatchEvent' message. It is an internal invariant check protecting the priority comparison logic.
Source
Thrown at dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/task/dispatcher/event/TaskDispatchableEvent.java:48
protected final V data;
protected final int dispatchTimes;
public TaskDispatchableEvent(long delayTimeMills, V data) {
this(delayTimeMills, data, 0);
}
public TaskDispatchableEvent(long delayTimeMills, V data, int dispatchTimes) {
super(delayTimeMills);
this.data = checkNotNull(data, "data is null");
this.dispatchTimes = dispatchTimes;
}
@Override
public int compareTo(Delayed other) {
if (!(other instanceof TaskDispatchableEvent)) {
throw new RuntimeException("The object being compared is not a TaskReadyForDispatchEvent.");
}
@SuppressWarnings("unchecked")
final TaskDispatchableEvent<V> otherEvent = (TaskDispatchableEvent<V>) other;
// For two retry events, we should compare the priority first, since the task delay time has already been
// expired.
if (dispatchTimes > 0 && otherEvent.dispatchTimes > 0) {
int priorityCompareResult = data.compareTo(otherEvent.data);
if (priorityCompareResult != 0) {
return priorityCompareResult;
}
return super.compareTo(otherEvent);
}
// For two new events, we should compare the delay time first, since the delay time is not expired.
// For two evens, if one is new another is retry, we should compare the delay time first
int delayTimeCompareResult = super.compareTo(otherEvent);View on GitHub (pinned to 02eac45a1b)
Solutions
- Ensure only TaskDispatchableEvent instances are enqueued into the dispatcher's DelayQueue.
- Fix the legacy error message to match the current class name (TaskDispatchableEvent) for diagnosability.
- If multiple Delayed types must share a queue, replace the raw cast with instanceof-based comparison instead of throwing.
- Update any plugin/custom code that adds foreign Delayed events to the queue.
Example fix
// before
if (!(other instanceof TaskDispatchableEvent)) {
throw new RuntimeException("The object being compared is not a TaskReadyForDispatchEvent.");
}
// after
if (!(other instanceof TaskDispatchableEvent)) {
return 1; // or sort by getDelay() to interleave foreign Delayed types
}
final TaskDispatchableEvent<?> otherEvent = (TaskDispatchableEvent<?>) other; Defensive patterns
Strategy: type-guard
Validate before calling
// before enqueueing into the dispatcher's DelayQueue
if (!(event instanceof TaskDispatchableEvent)) {
throw new IllegalArgumentException("Only TaskDispatchableEvent may be enqueued");
} Type guard
static <V> TaskDispatchableEvent<V> asDispatchable(Delayed d) {
return d instanceof TaskDispatchableEvent<V>
? (TaskDispatchableEvent<V>) d
: null;
} Try / catch
try {
queue.offer(event);
} catch (RuntimeException e) {
if (e.getMessage().contains("not a TaskReadyForDispatchEvent")) {
log.error("Foreign Delayed object in dispatch queue: {}", event.getClass(), e);
} else { throw e; }
} Prevention
- Keep the dispatcher DelayQueue exclusively for TaskDispatchableEvent instances.
- Update stale references/messages to the current class name to ease diagnosis.
- Add unit tests that cover the queue with only compatible event types.
When it happens
Trigger: Inserting or mixing a non-TaskDispatchableEvent Delayed object into the same DelayQueue used by the task dispatcher, causing priorityCompare -> compareTo to receive an incompatible element.
Common situations: Custom code or plugins enqueueing their own Delayed events into the dispatcher queue; refactors introducing a second Delayed event type into the shared queue; test harnesses substituting mock Delayed objects.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/ab6781cc0cc59c44.
Report an issue: GitHub.