{"record":{"id":"ab6781cc0cc59c44","repo":"apache/dolphinscheduler","slug":"the-object-being-compared-is-not-a-taskreadyfordi","errorCode":null,"errorMessage":"\"The object being compared is not a TaskReadyForDispatchEvent.\"","messagePattern":"\"The object being compared is not a TaskReadyForDispatchEvent\\.\"","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/task/dispatcher/event/TaskDispatchableEvent.java","lineNumber":48,"sourceCode":"\n    protected final V data;\n\n    protected final int dispatchTimes;\n\n    public TaskDispatchableEvent(long delayTimeMills, V data) {\n        this(delayTimeMills, data, 0);\n    }\n\n    public TaskDispatchableEvent(long delayTimeMills, V data, int dispatchTimes) {\n        super(delayTimeMills);\n        this.data = checkNotNull(data, \"data is null\");\n        this.dispatchTimes = dispatchTimes;\n    }\n\n    @Override\n    public int compareTo(Delayed other) {\n        if (!(other instanceof TaskDispatchableEvent)) {\n            throw new RuntimeException(\"The object being compared is not a TaskReadyForDispatchEvent.\");\n        }\n\n        @SuppressWarnings(\"unchecked\")\n        final TaskDispatchableEvent<V> otherEvent = (TaskDispatchableEvent<V>) other;\n\n        // For two retry events, we should compare the priority first, since the task delay time has already been\n        // expired.\n        if (dispatchTimes > 0 && otherEvent.dispatchTimes > 0) {\n            int priorityCompareResult = data.compareTo(otherEvent.data);\n            if (priorityCompareResult != 0) {\n                return priorityCompareResult;\n            }\n            return super.compareTo(otherEvent);\n        }\n\n        // For two new events, we should compare the delay time first, since the delay time is not expired.\n        // For two evens, if one is new another is retry, we should compare the delay time first\n        int delayTimeCompareResult = super.compareTo(otherEvent);","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/task/dispatcher/event/TaskDispatchableEvent.java#L30-L66","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nif (!(other instanceof TaskDispatchableEvent)) {\n    throw new RuntimeException(\"The object being compared is not a TaskReadyForDispatchEvent.\");\n}\n\n// after\nif (!(other instanceof TaskDispatchableEvent)) {\n    return 1; // or sort by getDelay() to interleave foreign Delayed types\n}\nfinal TaskDispatchableEvent<?> otherEvent = (TaskDispatchableEvent<?>) other;","handlingStrategy":"type-guard","validationCode":"// before enqueueing into the dispatcher's DelayQueue\nif (!(event instanceof TaskDispatchableEvent)) {\n    throw new IllegalArgumentException(\"Only TaskDispatchableEvent may be enqueued\");\n}","typeGuard":"static <V> TaskDispatchableEvent<V> asDispatchable(Delayed d) {\n    return d instanceof TaskDispatchableEvent<V>\n        ? (TaskDispatchableEvent<V>) d\n        : null;\n}","tryCatchPattern":"try {\n    queue.offer(event);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"not a TaskReadyForDispatchEvent\")) {\n        log.error(\"Foreign Delayed object in dispatch queue: {}\", event.getClass(), e);\n    } else { throw e; }\n}","preventionTips":["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."],"tags":["delay-queue","comparator","internal-invariant","class-cast"],"backgroundTag":"internal-invariant-violation","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}