{"record":{"id":"dee99776a8552d8a","repo":"flowable/flowable-engine","slug":"can-only-complete-a-case-instance-which-is-marked","errorCode":null,"errorMessage":"Can only complete a case instance which is marked as completeable. Check if there are active plan item instances.","messagePattern":"Can only complete a case instance which is marked as completeable\\. Check if there are active plan item instances\\.","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CompleteCaseInstanceCmd.java","lineNumber":32,"sourceCode":"\nimport org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntity;\nimport org.flowable.cmmn.engine.impl.util.CommandContextUtil;\nimport org.flowable.common.engine.api.FlowableIllegalArgumentException;\nimport org.flowable.common.engine.impl.interceptor.CommandContext;\n\n/**\n * @author Joram Barrez\n */\npublic class CompleteCaseInstanceCmd extends AbstractNeedsCaseInstanceCmd {\n\n    public CompleteCaseInstanceCmd(String caseInstanceId) {\n        super(caseInstanceId);\n    }\n    \n    @Override\n    protected void internalExecute(CommandContext commandContext, CaseInstanceEntity caseInstanceEntity) {\n        if (!caseInstanceEntity.isCompletable()) {\n            throw new FlowableIllegalArgumentException(\"Can only complete a case instance which is marked as completeable. Check if there are active plan item instances.\");\n        }\n        CommandContextUtil.getAgenda(commandContext).planCompleteCaseInstanceOperation(caseInstanceEntity);\n    }\n\n}\n","sourceCodeStart":14,"sourceCodeEnd":38,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CompleteCaseInstanceCmd.java#L14-L38","documentation":"CompleteCaseInstanceCmd only completes a case instance whose state is marked completable — meaning the case plan has no active plan item instances blocking completion. If caseInstanceEntity.isCompletable() is false, Flowable throws FlowableIllegalArgumentException instructing you to check for active plan item instances.","triggerScenarios":"Calling cmmnRuntimeService.completeCaseInstance(caseInstanceId) while the case still has active (not yet completed/terminated) plan item instances, so the case instance is not in the completable state.","commonSituations":"Attempting programmatic termination of a running case without first ending its active human tasks/stages; assuming completeCaseInstance works like process instance delete; racing with plan items still activating.","solutions":["Terminate/complete all active plan item instances (tasks, stages) first, then call completeCaseInstance.","If the case should be abandoned regardless, use cmmnRuntimeService.terminateCaseInstance(caseInstanceId) instead.","Query plan items first to confirm none active: cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(id).stateActive().count() == 0.","If you control the model, ensure the plan completes automatically (e.g. required/completion rules) so the instance reaches completable state."],"exampleFix":"// before\ncmmnRuntimeService.completeCaseInstance(caseInstanceId); // may throw if active plan items exist\n\n// after\nlong active = cmmnRuntimeService.createPlanItemInstanceQuery()\n    .caseInstanceId(caseInstanceId).stateActive().count();\nif (active > 0) {\n    cmmnRuntimeService.terminateCaseInstance(caseInstanceId);\n} else {\n    cmmnRuntimeService.completeCaseInstance(caseInstanceId);\n}","handlingStrategy":"try-catch","validationCode":"long active = cmmnRuntimeService.createPlanItemInstanceQuery().caseInstanceId(id).stateActive().count();\nboolean canComplete = active == 0;","typeGuard":null,"tryCatchPattern":"try { cmmnRuntimeService.completeCaseInstance(id); } catch (FlowableIllegalArgumentException e) { /* case not completable; terminate instead */ }","preventionTips":["Check for active plan item instances before completing a case.","Use terminateCaseInstance for abandoning cases with running work.","Model completion rules so cases reach completable state naturally."],"tags":["cmmn","case-instance","state","java"],"backgroundTag":"invalid-state-transition","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"}