flowable/flowable-engine · error · FlowableIllegalArgumentException
taskId is null
Error message
taskId is null
What it means
GetTaskVariableInstanceCmd.execute() validates its command arguments before doing any work. When the taskId passed to the command is null, it throws FlowableIllegalArgumentException('taskId is null') because a task variable instance cannot be looked up without a task id. This is a fail-fast guard protecting the downstream task service query from a pointless or dangerous null lookup.
Solutions
- Ensure a non-null taskId is passed: verify the value before calling taskService.getVariableInstance/getVariableInstanceLocal.
- If the taskId came from a previous query result, check that result for null/empty before using it.
- Fix the upstream data source (form field, process variable, request parameter) that produced a missing task id.
Example fix
// before
VariableInstance vi = cmmnTaskService.getVariableInstance(taskId, "status");
// after
if (taskId == null) {
throw new IllegalArgumentException("taskId must be resolved before fetching variables");
}
VariableInstance vi = cmmnTaskService.getVariableInstance(taskId, "status"); Defensive patterns
Strategy: validation
Validate before calling
if (taskId == null || taskId.isEmpty()) { throw new IllegalArgumentException("taskId is required"); } Type guard
boolean hasTaskId(String taskId) { return taskId != null && !taskId.isEmpty(); } Try / catch
try { return taskService.getVariableInstance(taskId, name); } catch (FlowableIllegalArgumentException e) { log.error("Bad argument: {}", e.getMessage()); throw e; } Prevention
- Resolve task ids from authoritative query results, never from nullable maps/params
- Add Objects.requireNonNull checks at API boundaries
- Use IDE null-analysis (@NonNull) on service method parameters
When it happens
Trigger: Calling CmmnTaskService.getVariableInstance(taskId, variableName) or getVariableInstanceLocal(taskId, variableName) with a null taskId; constructing GetTaskVariableInstanceCmd(null, name, isLocal) directly and executing it.
Common situations: taskId obtained from an unresolved/failed prior API call (e.g. task == null from a createTask/query result) and passed on unguarded; a Map- or form-sourced task id that was never populated; refactoring that dropped a null check between fetching and using the id.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f716be75f4212ddc.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/GetTaskVariableInstanceCmd.java:45
public class GetTaskVariableInstanceCmd implements Command<VariableInstance>, Serializable {
private static final long serialVersionUID = 1L;
protected String taskId;
protected String variableName;
protected boolean isLocal;
public GetTaskVariableInstanceCmd(String taskId, String variableName, boolean isLocal) {
this.taskId = taskId;
this.variableName = variableName;
this.isLocal = isLocal;
}
@Override
public VariableInstance execute(CommandContext commandContext) {
if (taskId == null) {
throw new FlowableIllegalArgumentException("taskId is null");
}
if (variableName == null) {
throw new FlowableIllegalArgumentException("variableName is null");
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
TaskEntity task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
if (task == null) {
throw new FlowableObjectNotFoundException("task " + taskId + " doesn't exist", Task.class);
}
VariableInstance variableEntity;
if (isLocal) {
variableEntity = task.getVariableInstanceLocal(variableName, false);
} else {
variableEntity = task.getVariableInstance(variableName, false);View on GitHub (pinned to d6d39ce1c6)