flowable/flowable-engine · error · FlowableIllegalStateException

Script content is null or evaluated to null for taskListener

Error message

Script content is null or evaluated to null for taskListener of type 'script'

What it means

ScriptTypeTaskListener evaluates the configured 'script' expression at execution time; if it evaluates to null there is no script content to run, so it throws FlowableIllegalStateException. This is the sibling check of the null-language error and indicates the script content expression resolved to nothing.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/listener/ScriptTypeTaskListener.java:61

    }

    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);
            }
        }
    }

    protected void validateParameters() {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Provide literal script content in the listener definition, or guarantee the referenced variable holding the script is set before the listener runs.
  2. Validate the case definition at deploy time to reject script listeners with empty/missing content.
  3. If the script must be dynamic, set the variable in a preceding plan item/listener and add a fallback expression (e.g. ${scriptVar ?: '/*noop*/'}).
  4. Log the resolved script expression scope during development to catch nulls early.

Example fix

// before
<flowable:taskListener event="create" language="javascript" script="${dynamicScriptVar}" /> <!-- var often null -->
// after
<flowable:taskListener event="create" language="javascript" script="execution.setVariable('processed', true)" />
Defensive patterns

Strategy: validation

Validate before calling

String script = scriptExpression != null ? String.valueOf(scriptExpression) : null;
if (script == null || script.isBlank()) throw new IllegalArgumentException("Script task listener content must be non-empty");

Type guard

boolean hasScript(FlowableListener l) {
    return l.getScriptInfo() != null && l.getScriptInfo().getScript() != null && !l.getScriptInfo().getScript().isBlank();
}

Try / catch

try {
    // task create triggers script listener
} catch (FlowableIllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("Script content is null")) {
        log.error("Script listener body unresolved; check script expression " + scriptExpr);
        throw new ConfigurationException("Provide literal or guaranteed script content", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: notify(delegateTask) evaluates this.script.getValue(delegateTask); after Objects.toString(..., null) the result is null — the script attribute was an expression resolving to null, or the script content is missing from the listener definition.

Common situations: script configured as ${scriptVar} where scriptVar is absent; template-generated CMMN XML with empty script body; variable holding the script text removed or renamed; script content supplied as empty string (may pass earlier checks but be rejected here depending on evaluation).

Related errors


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