flowable/flowable-engine · error · ActivitiException
Could no handle signal: no start activity found with id
Error message
Could no handle signal: no start activity found with id ${eventSubscription.getActivityId()} What it means
Thrown by SignalEventHandler.handleEvent when the event subscription's activityId does not match any start activity in the resolved process definition, i.e. processDefinition.findActivity(activityId) returns null. The signal was supposed to start/continue at a specific activity that no longer exists in the deployed model. Note the message's typo 'Could no handle signal' exists in the source.
Solutions
- Align the event subscription's activityId with the deployed model: redeploy the original BPMN or update/delete the stale subscription.
- Keep signal start event ids stable across versions of the process definition.
- Purge orphaned ACT_RU_EVENT_SUBSCRIBER rows whose activityId no longer exists in ACT_RE_PROCDEF's model.
- If the signal should start a fresh instance, verify the subscription was created for the correct (current) definition version.
Example fix
// before: renaming the start signal event id in the BPMN <signal id="orderSignal"/> <startEvent id="oldStartId"><signalEventDefinition signalRef="orderSignal"/></startEvent> // after: keep the id stable across versions <startEvent id="orderStart"><signalEventDefinition signalRef="orderSignal"/></startEvent>
Defensive patterns
Strategy: validation
Validate before calling
// keep signal start event ids stable; before redeploy, diff the BPMN ids
Set<String> startIds = model.getStartActivities().stream()
.map(ActivityImpl::getId).collect(Collectors.toSet());
if (!startIds.contains(subscriptionActivityId)) {
throw new IllegalStateException("Start activity missing in deployed model");
} Try / catch
try {
runtimeService.signalEventReceived("orderSignal");
} catch (org.activiti.engine.ActivitiException e) {
if (e.getMessage().contains("no start activity")) {
LOGGER.error("BPMN start event id changed; fix subscription/model");
}
} Prevention
- Never rename BPMN element ids across versions.
- Version-diff BPMN models in CI before deployment.
- Clean stale ACT_RU_EVENT_SUBSCRIBER rows after model changes.
When it happens
Trigger: A signal start-event subscription is handled but its activityId (stored when the subscription was created) is absent from the currently deployed process definition — e.g. the start event id was renamed in a new model version while the old subscription persisted.
Common situations: Renaming or removing a signal start event id in the BPMN XML and redeploying while old subscriptions survive in the runtime tables; DB restored from a snapshot with mismatched deployments; hand-crafted signal subscriptions.
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 throw process-instance scoped signal, since the…
- Could not find matching FlowElement for " +…
- Could not handle signal: no process instance started
- Could not handle signal: process definition with id: " +…
- Error while sending signal for event subscription
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/94dd480209e867fc.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/event/SignalEventHandler.java:60
@Override
public void handleEvent(EventSubscriptionEntity eventSubscription, Object payload, CommandContext commandContext) {
if (eventSubscription.getExecutionId() != null) {
super.handleEvent(eventSubscription, payload, commandContext);
} else if (eventSubscription.getProcessDefinitionId() != null) {
// Start event
String processDefinitionId = eventSubscription.getProcessDefinitionId();
DeploymentManager deploymentCache = Context
.getProcessEngineConfiguration()
.getDeploymentManager();
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) deploymentCache.findDeployedProcessDefinitionById(processDefinitionId);
if (processDefinition == null) {
throw new ActivitiObjectNotFoundException("No process definition found for id '" + processDefinitionId + "'", ProcessDefinition.class);
}
ActivityImpl startActivity = processDefinition.findActivity(eventSubscription.getActivityId());
if (startActivity == null) {
throw new ActivitiException("Could no handle signal: no start activity found with id " + eventSubscription.getActivityId());
}
ExecutionEntity processInstance = processDefinition.createProcessInstance(null, startActivity);
if (processInstance == null) {
throw new ActivitiException("Could not handle signal: no process instance started");
}
if (payload != null) {
if (payload instanceof Map) {
Map<String, Object> variables = (Map<String, Object>) payload;
processInstance.setVariables(variables);
}
}
processInstance.start();
} else {
throw new ActivitiException("Invalid signal handling: no execution nor process definition set");
}
}
View on GitHub (pinned to d6d39ce1c6)