flowable/flowable-engine · error · FlowableIllegalStateException
Cannot create 'script' task listener. Missing ScriptInfo.
Error message
Cannot create 'script' task listener. Missing ScriptInfo.
What it means
DefaultCmmnListenerFactory builds a ScriptTypeTaskListener from a FlowableListener. A script-type listener must carry a ScriptInfo (language + script); if listener.getScriptInfo() returns null the factory cannot construct the listener and throws FlowableIllegalStateException. This indicates malformed listener definition data — typically a model/parse bug or an incorrectly assembled FlowableListener.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/listener/DefaultCmmnListenerFactory.java:60
public TaskListener createClassDelegateTaskListener(FlowableListener listener) {
return classDelegateFactory.createLifeCycleListener(listener.getImplementation(), listener.getSourceState(), listener.getTargetState(), listener.getFieldExtensions());
}
@Override
public TaskListener createExpressionTaskListener(FlowableListener listener) {
return new ExpressionTaskListener(expressionManager.createExpression(listener.getImplementation()));
}
@Override
public TaskListener createDelegateExpressionTaskListener(FlowableListener listener) {
return new DelegateExpressionTaskListener(expressionManager.createExpression(listener.getImplementation()), listener.getFieldExtensions());
}
@Override
public TaskListener createScriptTypeTaskListener(FlowableListener listener) {
ScriptInfo scriptInfo = listener.getScriptInfo();
if (scriptInfo == null) {
throw new FlowableIllegalStateException("Cannot create 'script' task listener. Missing ScriptInfo.");
}
ScriptTypeTaskListener scriptListener = new ScriptTypeTaskListener(createExpression(listener.getScriptInfo().getLanguage()),
createExpression(listener.getScriptInfo().getScript()));
Optional.ofNullable(listener.getScriptInfo().getResultVariable())
.ifPresent(resultVar -> scriptListener.setResultVariable(createExpression(resultVar)));
return scriptListener;
}
protected Expression createExpression(Object value) {
return value instanceof String ? expressionManager.createExpression((String) value) : new FixedValue(value);
}
@Override
public PlanItemInstanceLifecycleListener createClassDelegateLifeCycleListener(FlowableListener listener) {
return classDelegateFactory.create(listener.getImplementation(), listener.getFieldExtensions());
}
@OverrideView on GitHub (pinned to d6d39ce1c6)
Solutions
- Fix the listener definition so the script element carries both language and script content, then redeploy the case definition.
- If building FlowableListener programmatically, call setScriptInfo(ScriptInfo) with non-null language/script before registering the listener.
- Validate the deployed case model (parse step) to catch missing ScriptInfo at deploy time instead of runtime.
- Check the Flowable version for known parser bugs around script listener metadata if definitions look correct.
Example fix
// before
FlowableListener listener = new FlowableListenerImpl();
listener.setEventType("create");
listener.setOnTransactionType("before-commit");
// after
FlowableListener listener = new FlowableListenerImpl();
listener.setEventType("create");
ScriptInfo scriptInfo = new ScriptInfoImpl("javascript", "task.setVariable('done', true)", null);
listener.setScriptInfo(scriptInfo); Defensive patterns
Strategy: validation
Validate before calling
if (listener.getScriptInfo() == null || listener.getScriptInfo().getScript() == null || listener.getScriptInfo().getLanguage() == null) {
throw new IllegalArgumentException("Script task listener requires ScriptInfo with language and script");
} Type guard
boolean hasScriptInfo(FlowableListener l) {
return l.getScriptInfo() != null
&& l.getScriptInfo().getLanguage() != null
&& l.getScriptInfo().getScript() != null;
} Try / catch
try {
TaskListener tl = listenerFactory.createScriptTypeTaskListener(listener);
} catch (FlowableIllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("Missing ScriptInfo")) {
throw new ModelValidationException("Listener definition lacks script info; fix case XML", e);
}
throw e;
} Prevention
- Validate CMMN models at deploy time for listener completeness
- When building FlowableListener programmatically, always set ScriptInfo
- Add schema/XML validation for script listener attributes in CI
When it happens
Trigger: createScriptTypeTaskListener(listener) is called for a listener whose type is script but whose ScriptInfo was never populated (e.g. the CMMN XML listener definition lacked script content, or a programmatically built FlowableListener omitted setScriptInfo).
Common situations: Hand-written or dynamically generated CMMN XML with a task listener marked as script but missing <script> details; custom model code building FlowableListener objects without ScriptInfo; parse/upgrade issue where ScriptInfo is dropped.
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
- The case instance id is mandatory, but '${caseInstanceId}' h
- ${delegateInstance.getClass().getName()} doesn't implement $
- Delegate expression ${expression} did not resolve to an impl
- 'language' evaluated to null for taskListener of type 'scrip
- No resource name provided
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e43edf23f9565ab8.
Report an issue: GitHub.