flowable/flowable-engine · error · FlowableException
is created by the process engine and should be completed vi
Error message
is created by the process engine and should be completed via the process engine API
What it means
Thrown by CompleteTaskWithFormCmd when the task being completed with a form has a non-empty processInstanceId, i.e. it was created by the BPMN process engine. As with plain completeTask, the CMMN engine refuses to complete a task it does not own; form-based completion must go through the engine that created the task.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CompleteTaskWithFormCmd.java:113
public CompleteTaskWithFormCmd(String taskId, String formDefinitionId, String outcome, Map<String,
Object> variables, Map<String, Object> variablesLocal, Map<String, Object> transientVariables, Map<String, Object> transientVariablesLocal) {
this(taskId, formDefinitionId, outcome, variables, transientVariables);
this.variablesLocal = variablesLocal;
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.getProcessInstanceId())) {
throw new FlowableException(task + " is created by the process engine and should be completed via the process engine API");
}
FormService formService = CommandContextUtil.getFormService(commandContext);
if (formService == null) {
throw new FlowableIllegalArgumentException("Form engine is not initialized");
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
FormRepositoryService formRepositoryService = CommandContextUtil.getFormRepositoryService(commandContext);
FormInfo formInfo = formRepositoryService.getFormModelById(formDefinitionId);
if (formInfo != null) {
// validate input at first
FormFieldHandler formFieldHandler = cmmnEngineConfiguration.getFormFieldHandler();
if (isFormFieldValidationEnabled(task)) {
formService.validateFormFields(task.getTaskDefinitionKey(), "humanTask", task.getScopeId(),
task.getScopeDefinitionId(), ScopeTypes.CMMN, formInfo, variables);
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Check task.getProcessInstanceId() before form completion and route process tasks to the BPMN completeTaskWithForm/TaskService API.
- Split task queries by processInstanceId vs caseInstanceId so each engine handles its own tasks.
- Refactor the task inbox to hold a reference to the originating engine per task.
Example fix
// before
cmmnTaskService.completeTaskWithForm(taskId, formDefinitionId, outcome, variables);
// after
if (task.getProcessInstanceId() != null) {
processTaskService.completeTaskWithForm(taskId, formDefinitionId, outcome, variables);
} else {
cmmnTaskService.completeTaskWithForm(taskId, formDefinitionId, outcome, variables);
} Defensive patterns
Strategy: validation
Validate before calling
org.flowable.task.api.Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
if (t != null && t.getProcessInstanceId() != null) {
processTaskService.completeTaskWithForm(taskId, formDefinitionId, outcome, variables);
} else {
cmmnTaskService.completeTaskWithForm(taskId, formDefinitionId, outcome, variables);
} Prevention
- Track each task's source engine in your task inbox model.
- Never mix CMMN form completion with BPMN-created tasks.
When it happens
Trigger: Calling CmmnTaskService.completeTaskWithForm(taskId, ...) on a task whose getProcessInstanceId() is not empty (a BPMN process user task).
Common situations: Generic task inbox completing both process and case tasks via the CMMN form API; migration from BPMN-only to CMMN code paths where task routing was not updated.
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
- is created by the process engine and should be completed vi
- Setting variable is not supported for read only delegate exe
- Can only trigger a plan item that is in the ACTIVE state
- No External Worker job found for id: ${externalJobId}
- ${workerId} does not hold a lock on the requested job
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/31670ebfab4981e1.
Report an issue: GitHub.