{"record":{"id":"24b5e06ca5dc708c","repo":"flowable/flowable-engine","slug":"case-instance-is-still-running-cannot-reactivate","errorCode":null,"errorMessage":"Case instance is still running, cannot reactivate historic case instance: ","messagePattern":"Case instance is still running, cannot reactivate historic case instance: ","errorType":"exception","errorClass":"FlowableIllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ReactivateHistoricCaseInstanceCmd.java","lineNumber":74,"sourceCode":"    }\n\n    @Override\n    public CaseInstance execute(CommandContext commandContext) {\n        if (reactivationBuilder.getCaseInstanceId() == null) {\n            throw new FlowableIllegalArgumentException(\"No historic case instance id provided\");\n        }\n\n        // Check if the historic case instance is found and if it is no longer running\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        HistoricCaseInstance instance = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager().createHistoricCaseInstanceQuery()\n            .caseInstanceId(reactivationBuilder.getCaseInstanceId())\n            .singleResult();\n\n        if (instance == null) {\n            throw new FlowableObjectNotFoundException(\"No historic case instance to be reactivated found with id: \" + reactivationBuilder.getCaseInstanceId(), HistoricCaseInstance.class);\n        }\n        if (instance.getEndTime() == null) {\n            throw new FlowableIllegalStateException(\"Case instance is still running, cannot reactivate historic case instance: \" + reactivationBuilder.getCaseInstanceId());\n        }\n\n        // move the case instance back to the runtime (this also checks, if the reactivation listener is even existent)\n        CaseInstanceEntity caseInstanceEntity = cmmnEngineConfiguration.getCaseInstanceHelper()\n            .copyHistoricCaseInstanceToRuntime(instance);\n\n        // reset the state to be active again and also set the last reactivation time as well as the current user triggering it\n        caseInstanceEntity.setState(CaseInstanceState.ACTIVE);\n        caseInstanceEntity.setLastReactivationTime(cmmnEngineConfiguration.getClock().getCurrentTime());\n        caseInstanceEntity.setLastReactivationUserId(Authentication.getAuthenticatedUserId());\n\n        // set case variables, if the builder contains any\n        if (reactivationBuilder.hasVariables()) {\n            caseInstanceEntity.setVariables(reactivationBuilder.getVariables());\n        }\n\n        // set transient case variables, if the builder contains any\n        if (reactivationBuilder.hasTransientVariables()) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ReactivateHistoricCaseInstanceCmd.java#L56-L92","documentation":"Thrown as FlowableIllegalStateException by ReactivateHistoricCaseInstanceCmd when the historic case instance looked up by reactivationBuilder.getCaseInstanceId() is still running (its END_TIME_ is null). Reactivation is only defined for completed (historic) case instances, so the engine refuses to reactivate a live one.","triggerScenarios":"Calling CaseInstanceStateManager/CmmnRuntimeService.reactivateCaseInstance(reactivationBuilder) with a caseInstanceId that refers to a case instance that is still active in the runtime tables rather than one that has ended.","commonSituations":"Passing a runtime case instance id instead of a historic one (ids are shared in Flowable); re-running a reactivation script against a case that was never completed; a race where the case completes after the caller checked.","solutions":["Verify with cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(id).singleResult() that endTime != null before reactivating","Use the correct id: fetch the finished instance via CmmnHistoryService and pass its id to the ReactivationBuilder","If the intent was to influence a running case, use plan item APIs (planItemInstanceQuery/complete/terminate) instead of reactivation","Close out the running case (terminate or complete it) first, then reactivate"],"exampleFix":"// before\nruntimeService.createCaseInstanceReactivationBuilder()\n    .caseInstanceId(anyInstanceId)\n    .reactivate();\n// after\nHistoricCaseInstance h = cmmnHistoryService.createHistoricCaseInstanceQuery()\n    .caseInstanceId(anyInstanceId).singleResult();\nif (h != null && h.getEndTime() != null) {\n    runtimeService.createCaseInstanceReactivationBuilder()\n        .caseInstanceId(h.getId())\n        .reactivate();\n}","handlingStrategy":"validation","validationCode":"HistoricCaseInstance h = cmmnHistoryService.createHistoricCaseInstanceQuery()\n    .caseInstanceId(id).singleResult();\nif (h == null) throw new IllegalArgumentException(\"no historic case instance \" + id);\nif (h.getEndTime() == null) throw new IllegalStateException(\"case instance still running: \" + id);","typeGuard":null,"tryCatchPattern":"try { runtimeService.createCaseInstanceReactivationBuilder().caseInstanceId(id).reactivate(); }\ncatch (FlowableIllegalStateException e) { /* case still running — resolve runtime instance instead */ }","preventionTips":["Always resolve the id via HistoricCaseInstanceQuery and confirm endTime is set","Distinguish runtime ids from historic ids in your code paths","Document that reactivation is only for completed cases"],"tags":["cmmn","case-instance","state","reactivation"],"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"}