flowable/flowable-engine · error · FlowableIllegalStateException
'language' evaluated to null for taskListener of type 'scrip
Error message
'language' evaluated to null for taskListener of type 'script'
What it means
ScriptTypeTaskListener executes its script via the ScriptingEngines at runtime. Before doing so it evaluates the configured 'language' expression; if it evaluates to null the engine cannot select a ScriptEngine and throws FlowableIllegalStateException. This means the language attribute/expression on the script task listener did not resolve to a usable value at execution time.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/listener/ScriptTypeTaskListener.java:57
protected Expression resultVariable;
public ScriptTypeTaskListener() {
}
public ScriptTypeTaskListener(Expression language, Expression script) {
this.script = script;
this.language = language;
}
@Override
public void notify(DelegateTask delegateTask) {
validateParameters();
ScriptingEngines scriptingEngines = CommandContextUtil.getCmmnEngineConfiguration().getScriptingEngines();
String language = Objects.toString(this.language.getValue(delegateTask), null);
if (language == null) {
throw new FlowableIllegalStateException("'language' evaluated to null for taskListener of type 'script'");
}
String script = Objects.toString(this.script.getValue(delegateTask), null);
if (script == null) {
throw new FlowableIllegalStateException("Script content is null or evaluated to null for taskListener of type 'script'");
}
ScriptEngineRequest.Builder request = ScriptEngineRequest.builder()
.script(script)
.language(language)
.scopeContainer(delegateTask)
.traceEnhancer(trace -> trace.addTraceTag("type", "taskListener"));
Object result = scriptingEngines.evaluate(request.build()).getResult();
if (resultVariable != null) {
String resultVariable = Objects.toString(this.resultVariable.getValue(delegateTask), null);
if (resultVariable != null) {
delegateTask.setVariable(resultVariable, result);
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Set the language attribute to a concrete value (e.g. 'javascript', 'groovy', 'juel') in the listener definition, or ensure the referenced variable exists on the task scope.
- Validate the CMMN XML so the script listener has both language and script attributes before deployment.
- If the language must be dynamic, populate the variable in a prior listener/plan item before the script listener executes.
- Confirm the scripting engine for the given language is on the classpath so the value is not discarded downstream.
Example fix
// before (CMMN XML)
<flowable:taskListener event="create" script="task.setVariable('x',1)" />
// after
<flowable:taskListener event="create" language="javascript" script="task.setVariable('x',1)" /> Defensive patterns
Strategy: validation
Validate before calling
String lang = scriptLanguageExpression != null ? String.valueOf(scriptLanguageExpression) : null;
if (lang == null || lang.isBlank()) throw new IllegalArgumentException("Script task listener language must be set"); Type guard
boolean hasLanguage(FlowableListener l) {
return l.getScriptInfo() != null && l.getScriptInfo().getLanguage() != null && !l.getScriptInfo().getLanguage().isBlank();
} Try / catch
try {
// task create triggers script listener
} catch (FlowableIllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("'language' evaluated to null")) {
log.error("Script listener language unresolved; check variable " + langVarName);
throw new ConfigurationException("Set a concrete scripting language on the listener", e);
}
throw e;
} Prevention
- Prefer literal language values over dynamic expressions
- Ensure variables referenced by the language expression exist on task scope
- Validate script listener attributes in the case model at deploy time
When it happens
Trigger: notify(delegateTask) evaluates this.language.getValue(delegateTask) and, after Objects.toString(..., null), gets null — the language was configured as a dynamic expression that resolves to null, or was left effectively unset in the listener definition.
Common situations: language set to an expression like ${langVar} where the variable is missing on the delegate task; XML attribute emptied by a template/generator; relying on a default language that is not applied in this code path; case data not populated before the listener fires.
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
- Script content is null or evaluated to null for taskListener
- The case instance id is mandatory, but '${caseInstanceId}' h
- Cannot create 'script' task listener. Missing ScriptInfo.
- scopeContainer cannot be null
- The service '${key}' is not available in the current context
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/998c437112d8cc72.
Report an issue: GitHub.