flowable/flowable-engine · error · IllegalArgumentException

The field 'language' should be set on the TaskListener

Error message

The field 'language' should be set on the TaskListener

What it means

ScriptTaskListener requires a 'language' field expression identifying the script engine (e.g. javascript, groovy). When the 'script' field is set but 'language' is missing, notify() throws this IllegalArgumentException before evaluating the script.

Source

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

    private static final long serialVersionUID = -8915149072830499057L;

    protected Expression script;

    protected Expression language;

    protected Expression resultVariable;

    protected boolean autoStoreVariables;

    @Override
    public void notify(DelegateTask delegateTask) {
        if (script == null) {
            throw new IllegalArgumentException("The field 'script' should be set on the TaskListener");
        }

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

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

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

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

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

    public void setLanguage(Expression language) {
        this.language = language;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Add <activiti:field name='language'><activiti:string>javascript</activiti:string></activiti:field> (or groovy, juel, etc.) to the ScriptTaskListener declaration
  2. Verify the script engine name matches a scripting engine registered with the ScriptingEngines of the process engine configuration
  3. Validate the process definition at deploy time to catch missing fields before runtime

Example fix

// before
<activiti:field name="script">
  <activiti:string>println(task.name)</activiti:string>
</activiti:field>
// after
<activiti:field name="script">
  <activiti:string>println(task.name)</activiti:string>
</activiti:field>
<activiti:field name="language">
  <activiti:string>javascript</activiti:string>
</activiti:field>
Defensive patterns

Strategy: validation

Validate before calling

// XML check before deployment
if (!xml.contains("name=\"language\"")) {
  throw new IllegalStateException("ScriptTaskListener is missing the 'language' field");
}

Try / catch

try {
  repositoryService.createDeployment().addClasspathResource(processXml).deploy();
} catch (IllegalArgumentException e) {
  // missing language field — fix BPMN config and redeploy
}

Prevention

When it happens

Trigger: A ScriptTaskListener configured with a 'script' field but no <activiti:field name='language'> element fires on a task event.

Common situations: BPMN XML where the author remembered the script but forgot the language field; renaming/refactoring listener configs that dropped the language element; assuming a default script language exists when none is configured.

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/c95d7454cc3b176d. Report an issue: GitHub.