flowable/flowable-engine · error · ActivitiException
destination ' ' not found. (referenced from transition in '…
Error message
destination '${destinationActivityName}' not found. (referenced from transition in '${sourceActivityId}') What it means
ActivitiException thrown in buildProcessDefinition when an unresolved transition's destination activity id does not match any activity in the finished process definition. Transitions are created with deferred destinations; resolution happens once, at build time, via processDefinition.findActivity. This indicates a dangling edge in the process graph.
Solutions
- Ensure the id passed to startTransition exactly matches an id used in startActivity(...) within the same builder.
- Create the destination activity before calling buildProcessDefinition().
- Log the source activity id (given in the message) and correct the reference or remove the orphan transition.
Example fix
// before
builder.startTransition("tskApprove"); // activity never declared
// after
builder.startActivity("tskApprove").endActivity();
builder.startActivity("tskStart").startTransition("tskApprove").endActivity(); // now resolves Defensive patterns
Strategy: validation
Validate before calling
Set<String> declared = new HashSet<>();
// ... collect ids passed to startActivity(...) ...
if (!declared.contains(transitionTargetId)) {
throw new IllegalArgumentException("transition target '" + transitionTargetId + "' is not a declared activity");
}
builder.buildProcessDefinition(); Try / catch
try {
PvmProcessDefinition def = builder.buildProcessDefinition();
} catch (ActivitiException e) {
if (e.getMessage() != null && e.getMessage().contains("not found")) {
log.error("Dangling transition reference in process model: " + e.getMessage());
}
throw e;
} Prevention
- Declare all activities before wiring transitions and calling buildProcessDefinition().
- Keep a set of declared activity ids and validate transition targets against it.
- Lint the BPMN model for unresolved targetRef values before conversion.
When it happens
Trigger: Calling startTransition(destId, ...) with an id that never matches an activity added via startActivity(id) (or the id was set after buildProcessDefinition), then calling buildProcessDefinition().
Common situations: Typos in target ids, referencing an activity defined in a different scope/process, or building the definition before all activities were declared (order of builder calls).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- destinationActivityId is null
- activity ' ' has duplicate transition
- Cannot start process instance, initial activity where the…
- couldn't execute event listener :
- duplicate activity id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/dc38e9732a9ce964.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/ProcessDefinitionBuilder.java:121
}
public ProcessDefinitionBuilder behavior(ActivityBehavior activityBehaviour) {
getActivity().setActivityBehavior(activityBehaviour);
return this;
}
public ProcessDefinitionBuilder property(String name, Object value) {
processElement.setProperty(name, value);
return this;
}
public PvmProcessDefinition buildProcessDefinition() {
for (Object[] unresolvedTransition : unresolvedTransitions) {
TransitionImpl transition = (TransitionImpl) unresolvedTransition[0];
String destinationActivityName = (String) unresolvedTransition[1];
ActivityImpl destination = processDefinition.findActivity(destinationActivityName);
if (destination == null) {
throw new ActivitiException("destination '" + destinationActivityName + "' not found. (referenced from transition in '" + transition.getSource().getId() + "')");
}
transition.setDestination(destination);
}
return processDefinition;
}
protected ActivityImpl getActivity() {
return (ActivityImpl) scopeStack.peek();
}
public ProcessDefinitionBuilder scope() {
getActivity().setScope(true);
return this;
}
public ProcessDefinitionBuilder executionListener(ExecutionListener executionListener) {
if (transition != null) {
transition.addExecutionListener(executionListener);View on GitHub (pinned to d6d39ce1c6)