{"record":{"id":"3dea4a8b3dba4f6a","repo":"flowable/flowable-engine","slug":"cannot-delete-a-task-that-is-part-of-a-case-instan-3dea4a","errorCode":null,"errorMessage":"Cannot delete a task that is part of a case instance.","messagePattern":"Cannot delete a task that is part of a case instance\\.","errorType":"http","errorClass":"FlowableForbiddenException","httpStatus":403,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskResource.java","lineNumber":161,"sourceCode":"            @ApiImplicitParam(name = \"cascadeHistory\", dataType = \"string\", value = \"Whether or not to delete the HistoricTask instance when deleting the task (if applicable). If not provided, this value defaults to false.\", paramType = \"query\"),\n            @ApiImplicitParam(name = \"deleteReason\", dataType = \"string\", value = \"Reason why the task is deleted. This value is ignored when cascadeHistory is true.\", paramType = \"query\")\n    })\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates the task was found and has been deleted. Response-body is intentionally empty.\"),\n            @ApiResponse(code = 403, message = \"Indicates the requested task cannot be deleted because it’s part of a workflow.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested task was not found.\")\n    })\n    @DeleteMapping(value = \"/runtime/tasks/{taskId}\")\n    @ResponseStatus(HttpStatus.NO_CONTENT)\n    public void deleteTask(@ApiParam(name = \"taskId\") @PathVariable String taskId, @ApiParam(hidden = true) @RequestParam(value = \"cascadeHistory\", required = false) Boolean cascadeHistory,\n                           @ApiParam(hidden = true) @RequestParam(value = \"deleteReason\", required = false) String deleteReason) {\n\n        Task taskToDelete = getTaskFromRequestWithoutAccessCheck(taskId);\n        if (taskToDelete.getExecutionId() != null) {\n            // Can not delete a task that is part of a process instance\n            throw new FlowableForbiddenException(\"Cannot delete a task that is part of a process instance.\");\n        } else if (taskToDelete.getScopeId() != null && ScopeTypes.CMMN.equals(taskToDelete.getScopeType())) {\n            throw new FlowableForbiddenException(\"Cannot delete a task that is part of a case instance.\");\n        }\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.deleteTask(taskToDelete);\n        }\n\n        if (cascadeHistory != null) {\n            // Ignore delete-reason since the task-history (where the reason is\n            // recorded) will be deleted anyway\n            taskService.deleteTask(taskToDelete.getId(), cascadeHistory);\n        } else {\n            // Delete with delete-reason\n            taskService.deleteTask(taskToDelete.getId(), deleteReason);\n        }\n    }\n\n    @ApiOperation(value = \"Get a task form\", tags = {\"Tasks\"})\n    @ApiResponses(value = {","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskResource.java#L143-L179","documentation":"A FlowableForbiddenException thrown by deleteTask when the task is scoped to a CMMN case instance (scopeId set and scopeType == CMMN). Like process-linked tasks, case tasks cannot be removed through the standalone task delete endpoint.","triggerScenarios":"DELETE /runtime/tasks/{taskId} on a task created inside a running CMMN case instance.","commonSituations":"Bulk task cleanup jobs crossing process and case tasks; applications mixing BPMN and CMMN engines unaware of scope rules.","solutions":["Terminate the case or the case's plan item instead of deleting the task directly","Use the CMMN REST API (case instances / plan items) to end the task via the engine","Skip CMMN-scoped tasks in cleanup logic (check scopeId/scopeType)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const task = await get('/runtime/tasks/'+taskId); if (task.scopeId != null && task.scopeType === 'cmmn') { /* use CMMN API instead */ }","typeGuard":"function isCmmnTask(t) { return t.scopeId != null && t.scopeType === 'cmmn'; }","tryCatchPattern":"catch (e) { if (e.status === 403 && /part of a case instance/.test(e.body && e.body.message)) { /* end via CMMN case/plan-item API */ } else throw e; }","preventionTips":["Check scopeId/scopeType before deleting runtime tasks","Route CMMN tasks to the CMMN REST endpoints","Exclude case tasks from BPMN-oriented cleanup scripts"],"tags":["rest","forbidden","cmmn","task-lifecycle"],"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"}