flowable/flowable-engine · error · ActivitiIllegalArgumentException

taskId is null

Error message

taskId is null

What it means

DeleteHistoricTaskInstanceCmd validates its taskId before touching history. A null taskId is rejected immediately with ActivitiIllegalArgumentException since no meaningful lookup or deletion is possible. This is a pure argument validation, not a lookup failure.

Solutions

  1. Ensure the caller passes a non-null taskId string before invoking deleteHistoricTask.
  2. Add a guard in the calling code (if (taskId == null) return/skip) for optional cleanup paths.
  3. Check where the id originates — e.g. use historicTaskInstance.getId() not the entity itself.

Example fix

// before
historyService.deleteHistoricTask(taskId); // taskId may be null
// after
if (taskId != null) {
    historyService.deleteHistoricTask(taskId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (taskId == null || taskId.isEmpty()) {
    return; // nothing to delete
}

Try / catch

try {
    historyService.deleteHistoricTask(taskId);
} catch (ActivitiIllegalArgumentException e) {
    log.warn("Skipping history deletion: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling deleteHistoricTask(null) on the history service — typically when the id came from an uninitialized variable, a missing query result, or an unbound method parameter.

Common situations: Bulk cleanup scripts building task ids from optional query results; refactoring where a HistoricTaskInstance object was passed instead of its id getter; asynchronous jobs where the id field was never populated.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/60d73f3748b36ebe. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/DeleteHistoricTaskInstanceCmd.java:38

import org.activiti.engine.impl.interceptor.CommandContext;

/**
 * @author Tom Baeyens
 */
public class DeleteHistoricTaskInstanceCmd implements Command<Object>, Serializable {

    private static final long serialVersionUID = 1L;
    protected String taskId;

    public DeleteHistoricTaskInstanceCmd(String taskId) {
        this.taskId = taskId;
    }

    @Override
    public Object execute(CommandContext commandContext) {

        if (taskId == null) {
            throw new ActivitiIllegalArgumentException("taskId is null");
        }
        commandContext
                .getHistoricTaskInstanceEntityManager()
                .deleteHistoricTaskInstanceById(taskId);
        return null;
    }

}

View on GitHub (pinned to d6d39ce1c6)