flowable/flowable-engine · error · FlowableIllegalArgumentException
task is null
Error message
task is null
What it means
SaveTaskCmd.execute throws FlowableIllegalArgumentException when the task passed to the command is null. The command persists changes to a TaskEntity, so a null task cannot be processed. This is the first validation in the command before any Flowable5 compatibility dispatching.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SaveTaskCmd.java:55
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
/**
* @author Joram Barrez
*/
public class SaveTaskCmd implements Command<Void>, Serializable {
private static final long serialVersionUID = 1L;
protected TaskEntity task;
public SaveTaskCmd(Task task) {
this.task = (TaskEntity) task;
}
@Override
public Void execute(CommandContext commandContext) {
if (task == null) {
throw new FlowableIllegalArgumentException("task is null");
}
if (task.getProcessDefinitionId() != null && Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, task.getProcessDefinitionId())) {
Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();
compatibilityHandler.saveTask(task);
return null;
}
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService();
if (task.getRevision() == 0) {
TaskHelper.insertTask(task, null, true, false);
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
if (eventDispatcher != null && eventDispatcher.isEnabled()) {
processEngineConfiguration.getEventDispatcher().dispatchEvent(FlowableTaskEventBuilder.createEntityEvent(FlowableEngineEventType.TASK_CREATED, task),
processEngineConfiguration.getEngineCfgKey());View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a non-null Task (typically a TaskEntity obtained from a task query) to saveTask.
- Verify singleResult() / a task lookup returned a task before calling saveTask.
- Use taskService.newTask() to create a new task rather than passing null.
Example fix
// before
Task task = taskService.createTaskQuery().taskId(id).singleResult();
taskService.saveTask(task); // NPE/flowable error if not found
// after
Task task = taskService.createTaskQuery().taskId(id).singleResult();
if (task != null) {
taskService.saveTask(task);
} Defensive patterns
Strategy: validation
Validate before calling
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
throw new IllegalArgumentException("Task " + taskId + " not found");
}
taskService.saveTask(task); Type guard
boolean isTaskPresent = task != null && task.getId() != null;
Prevention
- Never pass query singleResult() output to saveTask unchecked.
- Use taskService.newTask() to create tasks rather than fabricating nulls.
- Centralize task lookups in helpers that fail fast on missing tasks.
When it happens
Trigger: Calling taskService.saveTask(null) or executing new SaveTaskCmd(null).
Common situations: taskService.createTaskQuery()...singleResult() returned null (task not found) and the null result was passed to saveTask; a task variable was reassigned/cleared before saving; API misuse in test code.
Related errors
- taskId is required
- Error retrieving app engine info
- No deployment id available
- No resource name available
- appsDefinitionIds is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/45da1bfc066b210d.
Report an issue: GitHub.