{"record":{"id":"808b89c6ba38cdf8","repo":"flowable/flowable-engine","slug":"cannot-deploy-process-definition-processdefinit","errorCode":null,"errorMessage":"Cannot deploy process definition '${processDefinition.getResourceName()}': there already is a message event subscription for the message with name '${messageName}'. For ${eventSubscriptionEntity}","messagePattern":"Cannot deploy process definition '(.+?)': there already is a message event subscription for the message with name '(.+?)'\\. For (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/MessageStartEventActivityBehavior.java","lineNumber":62,"sourceCode":"        CommandContext commandContext = context.getCommandContext();\n        EventSubscriptionService eventSubscriptionService = context.getEventSubscriptionService();\n        ProcessDefinitionEntity processDefinition = context.getProcessDefinition();\n\n        String messageName = EventDefinitionExpressionUtil.determineMessageName(commandContext, messageEventDefinition, processDefinition);\n\n        // Skip the duplicate check when restoring a previous version's start events after the latest\n        // deployment was deleted: the just-deleted process definition's subscription is still in the in-session entity\n        // cache (the bulk delete in deleteEventSubscriptionsForProcessDefinition is queued, not flushed)\n        // and would trip a false-positive conflict.\n        if (!context.isRestoringPreviousVersion()) {\n            List<EventSubscriptionEntity> subscriptionsForSameMessageName = eventSubscriptionService\n                    .findEventSubscriptionsByName(MessageEventHandler.EVENT_HANDLER_TYPE, messageName, processDefinition.getTenantId());\n\n            for (EventSubscriptionEntity eventSubscriptionEntity : subscriptionsForSameMessageName) {\n                // throw exception only if there's already a subscription as start event\n                if (eventSubscriptionEntity.getProcessInstanceId() == null || eventSubscriptionEntity.getProcessInstanceId().isEmpty()) {\n                    // the event subscription has no instance-id, so it's a message start event\n                    throw new FlowableException(\"Cannot deploy process definition '\" + processDefinition.getResourceName()\n                            + \"': there already is a message event subscription for the message with name '\" + messageName + \"'. For \" + eventSubscriptionEntity);\n                }\n            }\n        }\n\n        MessageEventSubscriptionEntity newSubscription = eventSubscriptionService.createMessageEventSubscription();\n        newSubscription.setEventName(messageName);\n        newSubscription.setActivityId(context.getStartEvent().getId());\n        newSubscription.setConfiguration(processDefinition.getId());\n        newSubscription.setProcessDefinitionId(processDefinition.getId());\n\n        if (processDefinition.getTenantId() != null) {\n            newSubscription.setTenantId(processDefinition.getTenantId());\n        }\n\n        eventSubscriptionService.insertEventSubscription(newSubscription);\n        CountingEntityUtil.handleInsertEventSubscriptionEntityCount(newSubscription);\n    }","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/MessageStartEventActivityBehavior.java#L44-L80","documentation":"Thrown by MessageStartEventActivityBehavior.deploy when a new process definition is deployed containing a message start event whose message name already has an active start-event subscription (an EventSubscriptionEntity with no process instance id) in the same tenant. Flowable enforces that a message name can only be consumed by one message start event per tenant, otherwise a message would trigger multiple/ambiguous starts.","triggerScenarios":"repositoryService.deploy() of a process definition whose message start event uses a message name already subscribed by another deployed process definition's start event (same tenant), or redeploying/updating a definition when the old start-event subscription has not been removed.","commonSituations":"Two different process models accidentally reusing the same message name in their start events; deploying an updated BPMN while the previous version's start subscription lingers; multi-tenant deployments where the same message name is checked per tenant; copy-pasting a process model and forgetting to rename its start message.","solutions":["Rename the message on the new definition's message start event (message name attribute in BPMN XML / message element) so it is unique per tenant.","Remove or cancel the existing message start event subscription, e.g. by deleting the old process definition that owns it, before deploying the new one.","Query existing subscriptions (runtimeService.createEventSubscriptionQuery().eventName(messageName)) to find which definition holds the conflicting subscription and resolve it.","Deploy the updated definition under a different tenant if the same message name must coexist across tenants."],"exampleFix":"<!-- before: duplicate message name across definitions -->\n<message id=\"orderMsg\" name=\"orderReceived\"/>\n<!-- after: unique name for the new definition -->\n<message id=\"orderMsgV2\" name=\"orderReceivedV2\"/>","handlingStrategy":"validation","validationCode":"List<EventSubscription> subs = runtimeService.createEventSubscriptionQuery()\n    .eventType(\"message\").eventName(\"orderReceived\").list();\nboolean hasStartSubscription = subs.stream()\n    .anyMatch(s -> s.getProcessInstanceId() == null || s.getProcessInstanceId().isEmpty());\nif (hasStartSubscription) throw new IllegalStateException(\"message name already used by a start event\");","typeGuard":null,"tryCatchPattern":"try {\n    repositoryService.createDeployment().addClasspathResource(model).deploy();\n} catch (FlowableException ex) {\n    if (ex.getMessage() != null && ex.getMessage().contains(\"already is a message event subscription\")) {\n        logger.error(\"Conflicting message start event: {}\", ex.getMessage());\n    }\n    throw ex;\n}","preventionTips":["Globally unique message names per tenant across all process models (naming convention: <domain>.<event>.v1).","Grep BPMN resources for duplicate message names in CI before deploying.","Cancel old start-event subscriptions by removing/replacing the owning definition before re-deploying.","Use different tenants when the same message name must exist in separate lineages."],"tags":["bpmn","deployment","message-start-event","event-subscription"],"backgroundTag":"conflicting-config-options","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}