flowable/flowable-engine · error · FlowableIllegalStateException
Cannot create 'script' task listener. Missing ScriptInfo.
Error message
Cannot create 'script' task listener. Missing ScriptInfo.
What it means
DefaultListenerFactory.createScriptTypeTaskListener builds a ScriptTaskListener for a 'script'-type Flowable task listener, but the listener model carries no ScriptInfo (script text/language). The factory refuses to build a listener with nothing to execute and throws FlowableIllegalStateException. It is a BPMN parse-time configuration error, not a runtime execution failure.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/factory/DefaultListenerFactory.java:118
return new DelegateExpressionTaskListener(expressionManager.createExpression(listener.getImplementation()), createFieldDeclarations(listener.getFieldExtensions()));
}
@Override
public TransactionDependentTaskListener createTransactionDependentDelegateExpressionTaskListener(FlowableListener listener) {
return new DelegateExpressionTransactionDependentTaskListener(expressionManager.createExpression(listener.getImplementation()));
}
@Override
public TaskListener createScriptTypeTaskListener(FlowableListener listener) {
if (listener.getScriptInfo() != null) {
ScriptTypeTaskListener scriptListener = new ScriptTypeTaskListener(
createExpression(listener.getScriptInfo().getLanguage()),
listener.getScriptInfo().getScript());
Optional.ofNullable(listener.getScriptInfo().getResultVariable())
.ifPresent(resultVar -> scriptListener.setResultVariable(createExpression(resultVar)));
return scriptListener;
} else {
throw new FlowableIllegalStateException("Cannot create 'script' task listener. Missing ScriptInfo.");
}
}
protected Expression createExpression(Object value) {
return value instanceof String ? expressionManager.createExpression((String) value) : new FixedValue(value);
}
@Override
public ExecutionListener createClassDelegateExecutionListener(FlowableListener listener) {
return classDelegateFactory.create(listener.getImplementation(), createFieldDeclarations(listener.getFieldExtensions()));
}
@Override
public ExecutionListener createExpressionExecutionListener(FlowableListener listener) {
return new ExpressionExecutionListener(expressionManager.createExpression(listener.getImplementation()));
}
@OverrideView on GitHub (pinned to d6d39ce1c6)
Solutions
- Add the <flowable:script language="javascript"><![CDATA[...]]></flowable:script> element inside the task listener in the BPMN XML.
- When building the FlowableListener programmatically, call setScriptInfo with a ScriptInfo containing language and script before parsing/deployment.
- Validate the BPMN XML for listeners whose implementation type is 'script' but which lack a script child, before deployment.
- If the listener should not run a script, change the implementation type to class, expression, or delegate-expression instead.
Example fix
// before
FlowableListener listener = new FlowableListener();
listener.setEvent("create");
listener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_SCRIPT);
// after
FlowableListener listener = new FlowableListener();
listener.setEvent("create");
listener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_SCRIPT);
listener.setScriptInfo(new ScriptInfo("javascript", "println('hi')", null)); Defensive patterns
Strategy: validation
Validate before calling
if (listener.getImplementationType().equals(ImplementationType.IMPLEMENTATION_TYPE_SCRIPT)
&& (listener.getScriptInfo() == null
|| listener.getScriptInfo().getScript() == null)) {
throw new IllegalArgumentException("script task listener requires scriptInfo with script text");
} Type guard
boolean hasScriptInfo = l != null
&& ImplementationType.IMPLEMENTATION_TYPE_SCRIPT.equals(l.getImplementationType())
&& l.getScriptInfo() != null; Try / catch
try {
deploymentBuilder.deploy();
} catch (FlowableIllegalStateException e) {
if (e.getMessage().contains("Missing ScriptInfo")) {
// fix the listener definition before redeploying
} else { throw e; }
} Prevention
- Always pair IMPLEMENTATION_TYPE_SCRIPT with a ScriptInfo containing language and script.
- Add a unit test that parses all listener definitions before deployment.
- Use XSD/validator checks so script-less script listeners are caught at design time.
When it happens
Trigger: A FlowableListener with implementationType 'script' is parsed (e.g. <flowable:taskListener event="..." > with a script child or programmatic FlowableListener) but listener.getScriptInfo() returns null — no script element or ScriptInfo was attached to the listener definition.
Common situations: Hand-written or template-generated BPMN XML where the <script> block inside the task listener was omitted or misnamed; building listener models programmatically (e.g. via the Flowable model API) and forgetting setScriptInfo; XML transformations that drop child elements of the listener.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Cannot create 'script' type execution listener. Missing Scri
- Custom properties resolver delegate expression " + expressio
- BPMN XSD could not be found
- The bpmn 2.0 xml is not properly encoded
- ${delegateInstance.getClass().getName()} doesn't implement $
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/af8ff8c51cc9e1c9.
Report an issue: GitHub.