{"record":{"id":"c14f623b1d85e029","repo":"flowable/flowable-engine","slug":"is-created-by-the-process-engine-and-should-be-co","errorCode":null,"errorMessage":" is created by the process engine and should be completed via the process engine API","messagePattern":" is created by the process engine and should be completed via the process engine API","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CompleteTaskCmd.java","lineNumber":90,"sourceCode":"        this(taskId, variables, variablesLocal, transientVariables, transientVariablesLocal);\n        this.userId = userId;\n    }\n    \n    @Override\n    public Void execute(CommandContext commandContext) {\n        \n        if (taskId == null) {\n            throw new FlowableIllegalArgumentException(\"Null task id\");\n        }\n        \n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        TaskEntity taskEntity = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);\n        if (taskEntity == null) {\n            throw new FlowableObjectNotFoundException(\"Could not find task entity for id \" + taskId, TaskEntity.class);\n        }\n        \n        if (StringUtils.isNotEmpty(taskEntity.getProcessInstanceId())) {\n            throw new FlowableException(taskEntity + \" is created by the process engine and should be completed via the process engine API\");\n        }\n        \n        String planItemInstanceId = taskEntity.getSubScopeId();\n        PlanItemInstanceEntity planItemInstanceEntity = null;\n        if (planItemInstanceId != null) {\n            planItemInstanceEntity = cmmnEngineConfiguration.getPlanItemInstanceEntityManager().findById(planItemInstanceId);\n            if (planItemInstanceEntity == null) {\n                throw new FlowableException(\"Could not find plan item instance for \" + taskEntity);\n            }\n        }\n        \n        if (variables != null) {\n            taskEntity.setVariables(variables);\n        }\n        if (variablesLocal != null) {\n            taskEntity.setVariablesLocal(variablesLocal);\n        }\n        if (transientVariables != null) {","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CompleteTaskCmd.java#L72-L108","documentation":"Thrown when CompleteTaskCmd finds the task but the task has a non-empty processInstanceId, meaning it was created by the BPMN process engine, not the CMMN engine. The CMMN API refuses to complete it because lifecycle ownership belongs to the process engine; completing it via CMMN would corrupt the process state.","triggerScenarios":"Calling CmmnTaskService.completeTask(taskId) on a task whose TaskEntity.getProcessInstanceId() is set, i.e. a task created by a BPMN process (user task in a process definition) instead of a case plan item.","commonSituations":"Mixing engines: application looks up all tasks generically (e.g. taskService.createTaskQuery()) and completes them via the wrong engine's API; a shared task service where process and case tasks live side by side.","solutions":["Detect process tasks first (task.getProcessInstanceId() != null) and complete them with the BPMN TaskService: processTaskService.complete(taskId).","Route completion through the engine that created the task rather than a hardcoded CMMN task service.","If both engines share a task service, query with taskQuery().processInstanceId() vs caseInstanceId to split handling."],"exampleFix":"// before\ncmmnTaskService.completeTask(taskId);\n// after\norg.flowable.task.api.Task t = taskService.createTaskQuery().taskId(taskId).singleResult();\nif (t.getProcessInstanceId() != null) {\n    processTaskService.complete(taskId); // BPMN engine owns this task\n} else {\n    cmmnTaskService.completeTask(taskId);\n}","handlingStrategy":"validation","validationCode":"org.flowable.task.api.Task t = taskService.createTaskQuery().taskId(taskId).singleResult();\nif (t != null && t.getProcessInstanceId() != null) {\n    processTaskService.complete(taskId); // owned by BPMN engine\n} else {\n    cmmnTaskService.completeTask(taskId);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build a task dispatcher that routes completion to the engine that created the task.","Include the originating engine in your task DTO when aggregating tasks from both engines."],"tags":["cmmn","wrong-engine","task-lifecycle","flowable"],"backgroundTag":"unsupported-operation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}