flowable/flowable-engine · error · FlowableException
No sentry found for reference
Error message
No sentry found for reference ${entryCriterion.getSentryRef()} of entry criterion ${entryCriterion.getId()} What it means
During post-processing, each entry criterion's sentryRef must resolve to a <sentry> element declared in the same plan fragment/stage (its parent). If findSentry(sentryRef) returns null, this FlowableException is thrown: the entry criterion points to a sentry that does not exist.
Solutions
- Ensure every entryCriterion's sentryRef equals the id of a <sentry> declared within the same plan fragment/stage
- Re-add the missing <sentry> element or delete the orphan entry criterion
- Re-verify the case in the Flowable modeler so references are kept consistent
- Validate the file (XSD + conversion) before deployment to catch dangling refs early
Example fix
// before <entryCriterion sentryRef="sentryOld"/> <!-- sentryOld removed --> // after <entryCriterion sentryRef="sentry1"/> <!-- matches <sentry id="sentry1"> in same stage -->
Defensive patterns
Strategy: validation
Validate before calling
Set<String> sentryIds = collectIds(doc, "sentry");
for (Element c : doc.getElementsByTagName("entryCriterion")) {
String ref = c.getAttribute("sentryRef");
if (!sentryIds.contains(ref)) throw new DeploymentException("Unresolved entry 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("Entry criterion with dangling sentryRef: " + e.getMessage());
throw e;
} Prevention
- Delete sentries together with their criteria; check references both ways
- Declare sentries in the same stage/plan fragment as the criteria that use them
- Validate case models with the Flowable modeler or CI dry-run deployment
When it happens
Trigger: Deploying CMMN XML where <entryCriterion sentryRef="..."> references a sentry id that was deleted, renamed, declared in a different stage/plan fragment, or never defined.
Common situations: Removing sentries while leaving criteria behind, refactoring case diagrams in external tools, copy-pasting plan items with their criteria but not their sentries, and typos in sentryRef.
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/01cc629e01f5f148.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/CmmnXmlConverter.java:613
if (planItem.getItemControl().getParentCompletionRule() == null) {
ParentCompletionRule parentCompletionRule = new ParentCompletionRule();
parentCompletionRule.setType(ParentCompletionRule.IGNORE);
planItem.getItemControl().setParentCompletionRule(parentCompletionRule);
}
}
}
protected void resolveEntryCriteria(HasEntryCriteria hasEntryCriteria) {
for (Criterion entryCriterion : hasEntryCriteria.getEntryCriteria()) {
if (entryCriterion.getSentry() == null) {
// The timer event listener creates a fake sentry for the planItemStartTrigger.
// 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());
}
}
}
View on GitHub (pinned to d6d39ce1c6)