flowable/flowable-engine · error · FlowableException
Expression did not evaluate to a valid value (non empty…
Error message
Expression ${jobTopicExpression} did not evaluate to a valid value (non empty String). Was: ${topicValue}. For ${execution} What it means
External worker task behavior guard: the expression configured as the job topic evaluated to null or an empty string for the current execution, so no external worker job can be created and the behavior fails.
Solutions
- Fix the jobTopicExpression so it resolves to a non-empty string
- Use a static topic value instead of an expression
- Ensure variables referenced by the expression are set on the execution before the task
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ExternalWorkerTaskActivityBehavior.java:123 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4e0dcd7c98794f08.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ExternalWorkerTaskActivityBehavior.java:123
job.setRetries(jobServiceConfiguration.getAsyncExecutorNumberOfRetries());
// Inherit tenant id (if applicable)
if (execution.getTenantId() != null) {
job.setTenantId(execution.getTenantId());
}
Expression jobTopicExpression;
if (StringUtils.isEmpty(beforeContext.getJobTopicExpression())) {
jobTopicExpression = this.jobTopicExpression;
} else {
jobTopicExpression = processEngineConfiguration.getExpressionManager()
.createExpression(beforeContext.getJobTopicExpression());
}
Object topicValue = jobTopicExpression.getValue(execution);
if (topicValue != null && !topicValue.toString().isEmpty()) {
job.setJobHandlerConfiguration(topicValue.toString());
} else {
throw new FlowableException("Expression " + jobTopicExpression + " did not evaluate to a valid value (non empty String). Was: " + topicValue + ". For " + execution);
}
jobService.insertExternalWorkerJob(job);
if (interceptor != null) {
interceptor.afterCreateExternalWorkerJob(new CreateExternalWorkerJobAfterContext(
(ExternalWorkerServiceTask) currentFlowElement,
job,
execution
));
}
} else {
leave(execution);
}
}
@Override
public void trigger(DelegateExecution execution, String signalName, Object signalData) {View on GitHub (pinned to d6d39ce1c6)