flowable/flowable-engine · error · FlowableException
No sentry found for reference
Error message
No sentry found for reference ${exitCriterion.getSentryRef()} of exit criterion ${exitCriterion.getId()} What it means
Analogous to entry criteria, each exit criterion's sentryRef must resolve to a Sentry in the same parent element (stage or plan fragment). If it cannot be found, resolveExitCriteriaSentry throws this FlowableException during model post-processing.
Solutions
- Make every exitCriterion's sentryRef match a <sentry> id declared in the same parent stage/plan fragment
- Restore the deleted <sentry> or remove the orphan exit criterion
- Validate with the Flowable modeler and XSD/conversion checks before deployment
- Search the case XML for the unresolved sentryRef value to locate all broken references
Example fix
// before <exitCriterion sentryRef="exitSentry2"/> <!-- exitSentry2 not in this stage --> // after <exitCriterion sentryRef="exitSentry1"/> <!-- matches <sentry id="exitSentry1"> in same stage -->
Defensive patterns
Strategy: validation
Validate before calling
Set<String> sentryIds = collectIds(doc, "sentry");
for (Element c : doc.getElementsByTagName("exitCriterion")) {
String ref = c.getAttribute("sentryRef");
if (!sentryIds.contains(ref)) throw new DeploymentException("Unresolved exit sentryRef: " + ref);
} Try / catch
try {
repositoryService.createDeployment().addClasspathResource("case.cmmn.xml").deploy();
} catch (FlowableException e) {
if (e.getMessage().startsWith("No sentry found for reference"))
log.error("Exit criterion with dangling sentryRef: " + e.getMessage());
throw e;
} Prevention
- When moving plan items between stages, recreate their exit criteria/sentries in the target stage
- Run XSD validation plus a dry-run conversion/deployment before promoting case definitions
- Use the Flowable modeler so sentry references stay linked automatically
When it happens
Trigger: Deploying CMMN XML where <exitCriterion sentryRef="..."> references a non-existent, renamed, or out-of-scope sentry id on a plan item, stage, or plan fragment.
Common situations: Deleting a sentry used by exit criteria, moving plan items across stages (sentries are not shared across levels), hand-editing XML, or importing CMMN from third-party modeling tools with unlinked references.
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
- No matching plan item definition found for reference
- No sentry found for reference
- Could not resolve on part source reference
- e.getMessage()
- Error converting condition
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4b730022c260f9b5.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/CmmnXmlConverter.java:626
// Therefore only look for a sentry if it hasn't been set yet
Sentry sentry = entryCriterion.getParent().findSentry(entryCriterion.getSentryRef());
if (sentry != null) {
entryCriterion.setSentry(sentry);
} else {
throw new FlowableException("No sentry found for reference "
+ entryCriterion.getSentryRef() + " of entry criterion " + entryCriterion.getId());
}
}
}
}
protected void resolveExitCriteriaSentry(HasExitCriteria hasExitCriteria) {
for (Criterion exitCriterion : hasExitCriteria.getExitCriteria()) {
Sentry sentry = exitCriterion.getParent().findSentry(exitCriterion.getSentryRef());
if (sentry != null) {
exitCriterion.setSentry(sentry);
} else {
throw new FlowableException("No sentry found for reference "
+ exitCriterion.getSentryRef() + " of exit criterion " + exitCriterion.getId());
}
}
}
protected void processSentries(Stage planModelStage, PlanFragment planFragment) {
for (Sentry sentry : planFragment.getSentries()) {
for (SentryOnPart onPart : sentry.getOnParts()) {
PlanItem planItem = planModelStage.findPlanItemInPlanFragmentOrDownwards(onPart.getSourceRef());
if (planItem != null) {
onPart.setSource(planItem);
} else {
throw new FlowableException("Could not resolve on part source reference "
+ onPart.getSourceRef() + " of sentry " + sentry.getId());
}
}
}
View on GitHub (pinned to d6d39ce1c6)