flowable/flowable-engine · error · FlowableObjectNotFoundException
No case instance found for id ${caseInstanceEntityId}
Error message
No case instance found for id ${caseInstanceEntityId} What it means
TerminateCaseInstanceOperation.getCaseInstanceEntity lazily loads the case instance row via the CaseInstanceEntityManager. If no row exists for the stored id, the operation cannot proceed and throws FlowableObjectNotFoundException.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/agenda/operation/TerminateCaseInstanceOperation.java:151
return "cmmn-state-transition-terminate-case";
}
@Override
public void addAdditionalCallbackData(CallbackData callbackData) {
if (callbackData.getAdditionalData() == null) {
callbackData.setAdditionalData(new HashMap<>());
}
callbackData.getAdditionalData().put(CallbackConstants.EXIT_TYPE, exitType);
callbackData.getAdditionalData().put(CallbackConstants.EXIT_EVENT_TYPE, exitEventType);
callbackData.getAdditionalData().put(CallbackConstants.MANUAL_TERMINATION, manualTermination);
}
@Override
public CaseInstanceEntity getCaseInstanceEntity() {
if (caseInstanceEntity == null) {
caseInstanceEntity = CommandContextUtil.getCaseInstanceEntityManager(commandContext).findById(caseInstanceEntityId);
if (caseInstanceEntity == null) {
throw new FlowableObjectNotFoundException("No case instance found for id " + caseInstanceEntityId);
}
}
return caseInstanceEntity;
}
public boolean isManualTermination() {
return manualTermination;
}
public void setManualTermination(boolean manualTermination) {
this.manualTermination = manualTermination;
}
public String getExitCriterionId() {
return exitCriterionId;
}
public void setExitCriterionId(String exitCriterionId) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Verify the case instance id with CmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(id).count() before terminating.
- Treat the termination as already done if the instance no longer exists; catch FlowableObjectNotFoundException as a no-op.
- Check for concurrent terminate calls and serialize them.
- Ensure you are not passing a historic case instance id to a runtime API.
Example fix
// before
cmmnRuntimeService.terminateCaseInstance(caseInstanceId);
// after
if (cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstanceId).count() > 0) {
cmmnRuntimeService.terminateCaseInstance(caseInstanceId);
} Defensive patterns
Strategy: validation
Validate before calling
// java
long exists = cmmnRuntimeService.createCaseInstanceQuery()
.caseInstanceId(caseInstanceId).count();
if (exists == 0) return; // already gone; skip terminate Try / catch
try {
cmmnRuntimeService.terminateCaseInstance(caseInstanceId);
} catch (FlowableObjectNotFoundException e) {
// instance already terminated/removed: treat as success
} Prevention
- Resolve case instance ids from runtime queries, never from stale caches.
- Guard terminate operations against concurrent duplicate calls.
- Distinguish runtime vs historic ids.
When it happens
Trigger: Agenda operation created/referenced with a caseInstanceEntityId that no longer exists in ACT_CMMN_RU_CASE_INST — e.g. the case was already terminated/removed, or a wrong id was used to construct the operation/trigger the terminate command.
Common situations: Double termination racing so the second one finds no row; terminating with a stale case instance id from history (historic id reuse); database cleanup deleted runtime data.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Cannot find case instance for id ${caseInstanceId}
- Cannot find case instance with id
- Cannot find case instance with id
- Cannot find case instance with id
- Cannot find case instance with id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/323d78a1fc19c72a.
Report an issue: GitHub.