flowable/flowable-engine · error · IllegalArgumentException

The field 'script' should be set on the ExecutionListener

Error message

The field 'script' should be set on the ExecutionListener

What it means

Thrown as a plain IllegalArgumentException from ScriptExecutionListener.notify when the listener's 'script' field (an Expression set via <activiti:field name="script">) is null. The listener needs a script to evaluate and refuses to run without one.

Solutions

  1. Add the script field to the listener declaration: <activiti:field name="script"><activiti:string>your script</activiti:string></activiti:field>.
  2. Check the field name is exactly "script" and matches the listener's setScript property.
  3. If configuring programmatically, call setScript(expression) with a non-null Expression before execution.
  4. Ensure the field element actually contains a value (string or expression child), not an empty tag.

Example fix

// before: missing script field
<activiti:executionListener event="start" class="org.activiti.engine.impl.bpmn.listener.ScriptExecutionListener">
  <activiti:field name="language" value="javascript"/>
</activiti:executionListener>

// after
<activiti:executionListener event="start" class="org.activiti.engine.impl.bpmn.listener.ScriptExecutionListener">
  <activiti:field name="language" value="javascript"/>
  <activiti:field name="script"><activiti:string>execution.setVariable('x', 1);</activiti:string></activiti:field>
</activiti:executionListener>
Defensive patterns

Strategy: validation

Validate before calling

// validate the listener XML has both required fields before deployment
// e.g. parse the bpmn and check every ScriptExecutionListener declaration
assertListenerHasField(processDefinitionXml, "ScriptExecutionListener", "script");

Try / catch

try {
    repositoryService.createDeployment().addInputStream("p.bpmn", xml).deploy();
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("The field 'script' should be set")) {
        logger.error("ScriptExecutionListener missing <activiti:field name=\"script\">");
    }
    throw e;
}

Prevention

When it happens

Trigger: An <activiti:executionListener class="...ScriptExecutionListener"/> (or delegateExpression to it) is declared without the <activiti:field name="script"> element, or the field element has an empty/invalid expression so the injected Expression is null.

Common situations: Copy-pasting a ScriptExecutionListener declaration and forgetting the script field; using field name "script" misspelled (e.g. "scriptValue"); declaring the listener programmatically without calling setScript; XML where the field's string/expression child is missing.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/listener/ScriptExecutionListener.java:36

import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;

public class ScriptExecutionListener implements ExecutionListener {

    private static final long serialVersionUID = 1L;

    private Expression script;

    private Expression language;

    private Expression resultVariable;

    @Override
    public void notify(DelegateExecution execution) {

        if (script == null) {
            throw new IllegalArgumentException("The field 'script' should be set on the ExecutionListener");
        }

        if (language == null) {
            throw new IllegalArgumentException("The field 'language' should be set on the ExecutionListener");
        }

        ScriptingEngines scriptingEngines = Context.getProcessEngineConfiguration().getScriptingEngines();

        Object result = scriptingEngines.evaluate(script.getExpressionText(), language.getExpressionText(), execution);

        if (resultVariable != null) {
            execution.setVariable(resultVariable.getExpressionText(), result);
        }
    }

    public void setScript(Expression script) {
        this.script = script;
    }

View on GitHub (pinned to d6d39ce1c6)