flowable/flowable-engine · error · FlowableException
Case instance is still running, cannot delete
Error message
Case instance is still running, cannot delete
What it means
DeleteHistoricCaseInstanceCmd refuses to delete a historic case instance whose endTime is null, because that means the case is still running (only the historic mirror exists). Deleting running-case history would corrupt state, so a FlowableException is thrown with the instance appended to the message.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DeleteHistoricCaseInstanceCmd.java:59
@Override
public Object execute(CommandContext commandContext) {
if (caseInstanceId == null) {
throw new FlowableIllegalArgumentException("caseInstanceId is null");
}
// Check if case instance is still running
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
HistoricCaseInstanceEntity instance = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager().findById(caseInstanceId);
if (instance == null) {
throw new FlowableObjectNotFoundException("No historic case instance found with id: " + caseInstanceId, HistoricCaseInstance.class);
}
if (instance.isDeleted()) {
return null;
}
if (instance.getEndTime() == null) {
throw new FlowableException("Case instance is still running, cannot delete " + instance);
}
cmmnEngineConfiguration.getCmmnHistoryManager().recordHistoricCaseInstanceDeleted(caseInstanceId, instance.getTenantId());
return null;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Terminate/complete the case first, or delete the running case instance via the runtime API, then delete history
- Only target historic cases with a non-null endTime, e.g. query historicCaseInstanceQuery().finished()
- Skip still-running instances in batch cleanup scripts instead of failing the whole run
Example fix
// before
historyService.deleteHistoricCaseInstance(caseId);
// after
HistoricCaseInstance hci = historyService.createHistoricCaseInstanceQuery().caseInstanceId(caseId).singleResult();
if (hci != null && hci.getEndTime() != null) {
historyService.deleteHistoricCaseInstance(caseId);
} Defensive patterns
Strategy: validation
Validate before calling
HistoricCaseInstance hci = historyService.createHistoricCaseInstanceQuery().caseInstanceId(id).singleResult();
if (hci != null && hci.getEndTime() == null) { throw new IllegalStateException("case still running: " + id); } Type guard
boolean isFinished(HistoricCaseInstance hci) { return hci != null && hci.getEndTime() != null; } Try / catch
try { historyService.deleteHistoricCaseInstance(id); }
catch (FlowableException e) { if (e.getMessage() != null && e.getMessage().startsWith("Case instance is still running")) { /* defer until case ends */ } else throw e; } Prevention
- Query with .finished() before deleting historic cases
- Terminate running cases via runtime API before deleting their history
- Skip unfinished instances in batch history cleanup
When it happens
Trigger: Calling deleteHistoricCaseInstance(id) for a case instance that has not yet completed/terminated (no end time recorded).
Common situations: Cleanup scripts deleting history without filtering on finished cases; deleting history for an active case by mistake; assuming 'historic record exists' implies 'case is finished'.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Can only trigger a human task plan item that is in the ACTIV
- historic case instanceIds are null
- historic case instanceIds are empty
- caseInstanceId is null
- No historic case instance found with id:
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/226f1d4a1f53b59f.
Report an issue: GitHub.