flowable/flowable-engine · error · FlowableIllegalStateException
The historic case instance
Error message
The historic case instance <caseInstanceId> cannot be reactivated as there is no reactivation event in its CMMN model. You need to explicitly model the reactivation event in order to support case reactivation.
What it means
When reactivating a historic (completed/terminated) case instance, copyHistoricCaseInstanceToRuntime looks up the ReactivateEventListener in the case's CMMN model. Because reactivation behavior is always business-specific, Flowable refuses to guess: if the <case> element has no reactivation event listener modeled, it throws FlowableIllegalStateException instead of performing a default reactivation.
Solutions
- Add a reactivation event listener to the <case> element in the CMMN XML and redeploy the case definition.
- Configure the listener's plan item / behavior to define the business-specific reactivation logic.
- If reactivation is not required for this case, do not call the reactivation API; start a fresh case instance instead.
Example fix
// before: case XML without reactivation support, then runtimeService.createCaseInstanceBuilder().reactivate(historicId).start(); // throws // after: add to the <case> element in the CMMN model, redeploy, then reactivate // <extensionElements> // <flowable:reactivateEventListener /> // </extensionElements>
Defensive patterns
Strategy: try-catch
Validate before calling
CmmnModel model = cmmnRepositoryService.getCmmnModel(caseDefinitionId); Case caseModel = model.getMainProcess(); // Case element boolean canReactivate = caseModel != null && caseModel.getReactivateEventListener() != null;
Try / catch
try {
return runtimeService.createCaseInstanceBuilder().reactivate(historicCaseInstanceId).start();
} catch (FlowableIllegalStateException e) {
if (e.getMessage().contains("no reactivation event")) {
// fall back to starting a new case instance or inform the user reactivation is unsupported
}
throw e;
} Prevention
- Model a ReactivateEventListener in every <case> that must support reactivation.
- Add a deploy-time check that inspects the CMMN model for the listener when reactivation is a requirement.
- Re-check the listener after redeploying new versions of case definitions.
When it happens
Trigger: Calling CmmnRuntimeService.createCaseInstanceBuilder().reactivate(historicCaseInstanceId).start() (or CaseService reactivation APIs) on a case whose CMMN XML <case> does not declare a reactivation event listener.
Common situations: Deployed case model predates the reactivation feature (models created for older Flowable versions lack the listener); a new version of the case definition was deployed without the reactivation event while old historic instances still need reactivation; developer assumes reactivation works out of the box.
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
- a suspended
- Can only enable a plan item instance which is in state…
- Child form variables can only be set when starting a plan…
- Child task variables can only be set when starting a plan…
- Historic case instance has not ended and can only be…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/5f5e6c1d794e8af1.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceHelperImpl.java:249
/**
* This is the first part of reactivating a case instance from the history. It copies the historic data back to the runtime which is the case instance,
* its plan items and the variables. This method does not trigger the reactivation listener, just checks, if it is there, but there is no reactivation
* of plan items, etc. Just the copy of the historic data back to the runtime.
*
* @param commandContext the command context to execute within
* @param caseDefinition the case definition to get the case model from
* @param caseInstance the historic case instance to copy back to the runtime
* @return the copied runtime case instance entity for further processing
*/
protected CaseInstanceEntity copyHistoricCaseInstanceToRuntime(CommandContext commandContext, CaseDefinition caseDefinition, HistoricCaseInstance caseInstance) {
CmmnModel cmmnModel = getCmmnModel(commandContext, caseDefinition);
Case caseModel = getCaseModel(caseDefinition, cmmnModel);
ReactivateEventListener listener = caseModel.getReactivateEventListener();
if (listener == null) {
// the reactivation event listener must be present in order to reactivate the case, there is no generic way as it is always business driven
// on what happens during reactivation
throw new FlowableIllegalStateException("The historic case instance " + caseInstance.getId()
+ " cannot be reactivated as there is no reactivation event in its CMMN model. You need to explicitly model the reactivation event in order to support case reactivation.");
}
// recreate the case instance in the runtime data table from the historic one
return createCaseInstanceEntityFromHistoricCaseInstance(commandContext, caseInstance);
}
protected void createAsyncInitJob(CaseInstanceEntity caseInstance, CaseDefinition caseDefinition,
Case caseModel, JobService jobService, CommandContext commandContext) {
JobEntity job = JobUtil.createJob(caseInstance, caseModel, AsyncInitializePlanModelJobHandler.TYPE, cmmnEngineConfiguration);
job.setElementId(caseDefinition.getId());
job.setElementName(caseDefinition.getName());
job.setJobHandlerConfiguration(caseInstance.getId());
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}View on GitHub (pinned to d6d39ce1c6)