flowable/flowable-engine · error · FlowableException
The is created by the cmmn engine and should be completed…
Error message
The is created by the cmmn engine and should be completed via the cmmn engine API
What it means
CompleteTaskWithFormCmd refuses to complete a task that was created by the CMMN engine. Such tasks are owned and lifecycle-managed by the CMMN engine, so completing them through the process (BPMN) task-form API would bypass CMMN state management. The library throws a plain FlowableException to force callers onto the correct engine API.
Solutions
- Check task.getScopeType() before completing; if it is 'cmmn', call the CMMN engine API instead: CmmnTaskService.completeTaskWithForm(taskId, formDefinitionId, formOutcome, variables).
- Inspect the task (taskService.createTaskQuery().taskId(id).singleResult()) to see scopeType/scopeId and route to the proper service programmatically.
- If the task should not be a CMMN task, fix the deployment: it was started from a case definition, not a process definition.
Example fix
// before
taskService.completeTaskWithForm(taskId, formId, outcome, vars);
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (ScopeTypes.CMMN.equals(task.getScopeType())) {
cmmnTaskService.completeTaskWithForm(taskId, formId, outcome, vars);
} else {
taskService.completeTaskWithForm(taskId, formId, outcome, vars);
} Defensive patterns
Strategy: type-guard
Validate before calling
Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
boolean isCmmnTask = t != null && "cmmn".equals(t.getScopeType());
if (isCmmnTask) { /* route to cmmnTaskService.completeTaskWithForm(...) */ } Type guard
boolean isCmmnTask(Task t) { return t != null && ScopeTypes.CMMN.equals(t.getScopeType()); } Try / catch
try {
taskService.completeTaskWithForm(taskId, formId, outcome, vars);
} catch (FlowableException e) {
if (e.getMessage().contains("cmmn engine")) {
cmmnTaskService.completeTaskWithForm(taskId, formId, outcome, vars);
} else { throw e; }
} Prevention
- Centralize task completion in one service that checks scopeType before dispatching to BPMN or CMMN API
- Never call BPMN task-form APIs from case-related screens
- Store scopeType alongside task ids in UI state
When it happens
Trigger: Calling TaskService.completeTaskWithForm (or the CompleteTaskWithFormCmd command directly) on a TaskEntity whose scopeId is set and whose scopeType equals ScopeTypes.CMMN, i.e. a task originating from a CMMN case rather than a BPMN process.
Common situations: Applications that mix BPMN processes and CMMN cases and use a generic 'complete task with form' endpoint keyed only by taskId; after migration to Flowable 6 where CMMN-managed tasks appear in the same task queries as BPMN tasks; UI task lists that do not distinguish task scope.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/9625678074d68de8.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/CompleteTaskWithFormCmd.java:110
Object> variables, Map<String, Object> variablesLocal, Map<String, Object> transientVariables, Map<String, Object> transientVariablesLocal) {
this(taskId, formDefinitionId, outcome, variables);
this.variablesLocal = variablesLocal;
this.transientVariables = transientVariables;
this.transientVariablesLocal = transientVariablesLocal;
}
public CompleteTaskWithFormCmd(String taskId, String formDefinitionId, String outcome, String userId,
Map<String, Object> variables, Map<String, Object> variablesLocal,
Map<String, Object> transientVariables, Map<String, Object> transientVariablesLocal) {
this(taskId, formDefinitionId, outcome, variables, variablesLocal, transientVariables, transientVariablesLocal);
this.userId = userId;
}
@Override
protected Void execute(CommandContext commandContext, TaskEntity task) {
if (StringUtils.isNotEmpty(task.getScopeId()) && ScopeTypes.CMMN.equals(task.getScopeType())) {
throw new FlowableException("The " + task + " is created by the cmmn engine and should be completed via the cmmn engine API");
}
FormService formService = CommandContextUtil.getFormService();
if (formService == null) {
throw new FlowableIllegalArgumentException("Form engine is not initialized");
}
FormRepositoryService formRepositoryService = CommandContextUtil.getFormRepositoryService();
FormInfo formInfo = formRepositoryService.getFormModelById(formDefinitionId);
Map<String, Object> formVariables;
boolean local = variablesLocal != null && !variablesLocal.isEmpty();
if (local) {
formVariables = variablesLocal;
} else {
formVariables = variables;
}
Map<String, Object> taskVariables = null;View on GitHub (pinned to d6d39ce1c6)