flowable/flowable-engine · error · FlowableIllegalArgumentException

Null task id

Error message

Null task id

What it means

CompleteTaskCmd.execute() begins by validating that a task id was supplied; a null taskId causes FlowableIllegalArgumentException("Null task id"). This is a fail-fast guard before any engine lookup happens.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CompleteTaskCmd.java:80

            Map<String, Object> transientVariables, Map<String, Object> transientVariablesLocal) {
        
        this(taskId, variables, transientVariables);
        this.variablesLocal = variablesLocal;
        this.transientVariablesLocal = transientVariablesLocal;
    }
    
    public CompleteTaskCmd(String taskId, String userId, Map<String, Object> variables, Map<String, Object> variablesLocal,
            Map<String, Object> transientVariables, Map<String, Object> transientVariablesLocal) {
        
        this(taskId, variables, variablesLocal, transientVariables, transientVariablesLocal);
        this.userId = userId;
    }
    
    @Override
    public Void execute(CommandContext commandContext) {
        
        if (taskId == null) {
            throw new FlowableIllegalArgumentException("Null task id");
        }
        
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        TaskEntity taskEntity = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
        if (taskEntity == null) {
            throw new FlowableObjectNotFoundException("Could not find task entity for id " + taskId, TaskEntity.class);
        }
        
        if (StringUtils.isNotEmpty(taskEntity.getProcessInstanceId())) {
            throw new FlowableException(taskEntity + " is created by the process engine and should be completed via the process engine API");
        }
        
        String planItemInstanceId = taskEntity.getSubScopeId();
        PlanItemInstanceEntity planItemInstanceEntity = null;
        if (planItemInstanceId != null) {
            planItemInstanceEntity = cmmnEngineConfiguration.getPlanItemInstanceEntityManager().findById(planItemInstanceId);
            if (planItemInstanceEntity == null) {
                throw new FlowableException("Could not find plan item instance for " + taskEntity);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a non-null task id to cmmnTaskService.complete(taskId).
  2. Validate the id in the caller (e.g. @NotBlank on the DTO / early null check) before invoking the API.
  3. If the id came from a query result, check the entity exists before reading its id.

Example fix

// before
String taskId = request.getTaskId(); // may be null
cmmnTaskService.complete(taskId);

// after
if (request.getTaskId() == null || request.getTaskId().isBlank()) {
    throw new IllegalArgumentException("taskId is required");
}
cmmnTaskService.complete(request.getTaskId());
Defensive patterns

Strategy: validation

Validate before calling

if (taskId == null || taskId.isBlank()) throw new IllegalArgumentException("taskId is required");

Try / catch

try { cmmnTaskService.complete(taskId); } catch (FlowableIllegalArgumentException e) { /* null id */ } catch (FlowableObjectNotFoundException e) { /* unknown id */ }

Prevention

When it happens

Trigger: Calling cmmnTaskService.complete(null), or complete(variables) style overloads where the id variable resolved to null.

Common situations: Task id extracted from a request/DTO that omitted it; a prior query returned no result and its id field was null; constructor CompleteTaskCmd(null) from custom code.

Related errors


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