apache/dolphinscheduler · error · IllegalArgumentException

taskInstanceId cannot be null

Error message

taskInstanceId cannot be null

What it means

TaskInstanceContextDaoImpl.deleteByTaskInstanceIdAndContextType removes context rows for a given task instance and context type. The task instance id is the primary lookup key, so a null value is rejected with IllegalArgumentException before the mapper executes.

Source

Thrown at dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/TaskInstanceContextDaoImpl.java:61

            TaskInstanceContextDao {

    public TaskInstanceContextDaoImpl(TaskInstanceContextMapper taskInstanceContextMapper) {
        super(taskInstanceContextMapper);
    }

    @Override
    public List<TaskInstanceContext> queryListByTaskInstanceIdAndContextType(Integer taskInstanceId,
                                                                             ContextType contextType) {
        if (taskInstanceId == null) {
            return Collections.emptyList();
        }
        return mybatisMapper.queryListByTaskInstanceIdAndContextType(taskInstanceId, contextType);
    }

    @Override
    public int deleteByTaskInstanceIdAndContextType(Integer taskInstanceId, ContextType contextType) {
        if (taskInstanceId == null) {
            throw new IllegalArgumentException("taskInstanceId cannot be null");
        }
        return mybatisMapper.deleteByTaskInstanceIdAndContextType(taskInstanceId, contextType);
    }

    @Override
    public int upsertTaskInstanceContext(TaskInstanceContext taskInstanceContext) {
        if (taskInstanceContext == null) {
            return 0;
        }
        TaskInstanceContext dbTaskInstanceContext =
                mybatisMapper.queryListByTaskInstanceIdAndContextType(taskInstanceContext.getTaskInstanceId(),
                        taskInstanceContext.getContextType()).stream().findFirst().orElse(null);
        if (dbTaskInstanceContext == null) {
            return mybatisMapper.insert(taskInstanceContext);
        } else {
            List<AbstractTaskInstanceContext> dbDependentResultTaskInstanceContextList =
                    dbTaskInstanceContext.getTaskInstanceContext();
            dbDependentResultTaskInstanceContextList.addAll(taskInstanceContext.getTaskInstanceContext());

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Ensure the task instance is persisted and has a valid id before deleting its contexts.
  2. Null-check the TaskInstance/id at the call site and skip deletion when absent.
  3. Verify the ordering: fetch the task instance from the DB first, then clean up contexts.

Example fix

// before
taskInstanceContextDao.deleteByTaskInstanceIdAndContextType(taskInstance.getId(), ContextType.CACHE);
// after
if (taskInstance != null && taskInstance.getId() != null) {
    taskInstanceContextDao.deleteByTaskInstanceIdAndContextType(taskInstance.getId(), ContextType.CACHE);
}
Defensive patterns

Strategy: validation

Validate before calling

if (taskInstance == null || taskInstance.getId() == null) {
    return;
}
taskInstanceContextDao.deleteByTaskInstanceIdAndContextType(taskInstance.getId(), contextType);

Type guard

boolean hasValidId(TaskInstance t) { return t != null && t.getId() != null; }

Try / catch

try {
    dao.deleteByTaskInstanceIdAndContextType(id, contextType);
} catch (IllegalArgumentException e) {
    log.error("taskInstanceId is required for context deletion", e);
}

Prevention

When it happens

Trigger: Calling deleteByTaskInstanceIdAndContextType(null, someContextType), generally when the TaskInstance object feeding the id was null or its id was not yet generated (task not persisted).

Common situations: Cleanup logic after task failure that references a task instance never persisted; callers passing taskInstance.getId() on a newly constructed (unsaved) instance.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/9323f1313d4b6cdb. Report an issue: GitHub.