flowable/flowable-engine · error · FlowableException

no topic expression configured for

Error message

no topic expression configured for 

What it means

ExternalWorkerTaskActivityBehavior creates an external worker job for the plan item. The job's topic comes from a topic expression string; if it is null or empty after interceptor processing, no topic can be assigned and the engine throws this FlowableException before creating the job.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/ExternalWorkerTaskActivityBehavior.java:67

    @Override
    public void execute(CommandContext commandContext, PlanItemInstanceEntity planItemInstanceEntity) {
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        CreateCmmnExternalWorkerJobInterceptor interceptor = cmmnEngineConfiguration.getCreateCmmnExternalWorkerJobInterceptor();

        CreateCmmnExternalWorkerJobBeforeContext beforeContext = new CreateCmmnExternalWorkerJobBeforeContext(
                serviceTask,
                planItemInstanceEntity,
                getJobCategory(serviceTask),
                serviceTask.getTopic()
        );

        if (interceptor != null) {
            interceptor.beforeCreateExternalWorkerJob(beforeContext);
        }

        String jobTopicExpression = beforeContext.getJobTopicExpression();
        if (StringUtils.isEmpty(jobTopicExpression)) {
            throw new FlowableException("no topic expression configured for " + planItemInstanceEntity);
        }

        JobServiceConfiguration jobServiceConfiguration = cmmnEngineConfiguration.getJobServiceConfiguration();
        JobService jobService = jobServiceConfiguration.getJobService();

        ExternalWorkerJobEntity job = jobService.createExternalWorkerJob();
        job.setSubScopeId(planItemInstanceEntity.getId());
        job.setScopeId(planItemInstanceEntity.getCaseInstanceId());
        job.setScopeDefinitionId(planItemInstanceEntity.getCaseDefinitionId());
        job.setScopeType(ScopeTypes.CMMN);
        job.setElementId(serviceTask.getId());
        job.setElementName(serviceTask.getName());
        job.setJobHandlerType(ExternalWorkerTaskCompleteJobHandler.TYPE);
        job.setExclusive(serviceTask.isExclusive());

        if (StringUtils.isNotEmpty(beforeContext.getJobCategory())) {
                Expression categoryExpression = CommandContextUtil.getExpressionManager(commandContext)
                        .createExpression(beforeContext.getJobCategory());

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Set the topic attribute on the external worker task element in the CMMN model, e.g. <externalWorkerTask topic="myTopic"> or a topic expression.
  2. Redeploy the corrected case model so the plan item definition carries the topic.
  3. If the topic comes from an expression, ensure the referenced variable is populated before activation.

Example fix

// before
<serviceTask xmlns="http://flowable.org/cmmn" type="external-worker-task"/> <!-- no topic -->
// after
<serviceTask xmlns="http://flowable.org/cmmn" type="external-worker-task" topic="loan-processing"/>
Defensive patterns

Strategy: validation

Validate before calling

String topic = externalWorkerTask.getTopic();
if (topic == null || topic.isBlank()) {
    throw new IllegalArgumentException("External worker task must define a topic: " + elementId);
}

Try / catch

try {
    caseRuntimeService.triggerPlanItemInstance(planItemId);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("no topic expression configured")) {
        log.error("External worker task missing topic in case model");
    }
    throw e;
}

Prevention

When it happens

Trigger: Activating an external worker task plan item whose topic expression attribute is empty or null in beforeContext.getJobTopicExpression().

Common situations: External worker task element in the case model missing the topic attribute; a model transformation/deployment dropped the attribute; topic supplied conditionally via expression that resolved to empty.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/0df7d39ea93ddd8a. Report an issue: GitHub.