{"record":{"id":"af8ff8c51cc9e1c9","repo":"flowable/flowable-engine","slug":"cannot-create-script-task-listener-missing-scri-af8ff8","errorCode":null,"errorMessage":"Cannot create 'script' task listener. Missing ScriptInfo.","messagePattern":"Cannot create 'script' task listener\\. Missing ScriptInfo\\.","errorType":"validation","errorClass":"FlowableIllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/factory/DefaultListenerFactory.java","lineNumber":118,"sourceCode":"        return new DelegateExpressionTaskListener(expressionManager.createExpression(listener.getImplementation()), createFieldDeclarations(listener.getFieldExtensions()));\n    }\n\n    @Override\n    public TransactionDependentTaskListener createTransactionDependentDelegateExpressionTaskListener(FlowableListener listener) {\n        return new DelegateExpressionTransactionDependentTaskListener(expressionManager.createExpression(listener.getImplementation()));\n    }\n\n    @Override\n    public TaskListener createScriptTypeTaskListener(FlowableListener listener) {\n        if (listener.getScriptInfo() != null) {\n            ScriptTypeTaskListener scriptListener = new ScriptTypeTaskListener(\n                    createExpression(listener.getScriptInfo().getLanguage()),\n                    listener.getScriptInfo().getScript());\n            Optional.ofNullable(listener.getScriptInfo().getResultVariable())\n                    .ifPresent(resultVar -> scriptListener.setResultVariable(createExpression(resultVar)));\n            return scriptListener;\n        } else {\n            throw new FlowableIllegalStateException(\"Cannot create 'script' task listener. Missing ScriptInfo.\");\n        }\n    }\n\n    protected Expression createExpression(Object value) {\n        return value instanceof String ? expressionManager.createExpression((String) value) : new FixedValue(value);\n    }\n\n    @Override\n    public ExecutionListener createClassDelegateExecutionListener(FlowableListener listener) {\n        return classDelegateFactory.create(listener.getImplementation(), createFieldDeclarations(listener.getFieldExtensions()));\n    }\n\n    @Override\n    public ExecutionListener createExpressionExecutionListener(FlowableListener listener) {\n        return new ExpressionExecutionListener(expressionManager.createExpression(listener.getImplementation()));\n    }\n\n    @Override","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/parser/factory/DefaultListenerFactory.java#L100-L136","documentation":"DefaultListenerFactory.createScriptTypeTaskListener builds a ScriptTaskListener for a 'script'-type Flowable task listener, but the listener model carries no ScriptInfo (script text/language). The factory refuses to build a listener with nothing to execute and throws FlowableIllegalStateException. It is a BPMN parse-time configuration error, not a runtime execution failure.","triggerScenarios":"A FlowableListener with implementationType 'script' is parsed (e.g. <flowable:taskListener event=\"...\" > with a script child or programmatic FlowableListener) but listener.getScriptInfo() returns null — no script element or ScriptInfo was attached to the listener definition.","commonSituations":"Hand-written or template-generated BPMN XML where the <script> block inside the task listener was omitted or misnamed; building listener models programmatically (e.g. via the Flowable model API) and forgetting setScriptInfo; XML transformations that drop child elements of the listener.","solutions":["Add the <flowable:script language=\"javascript\"><![CDATA[...]]></flowable:script> element inside the task listener in the BPMN XML.","When building the FlowableListener programmatically, call setScriptInfo with a ScriptInfo containing language and script before parsing/deployment.","Validate the BPMN XML for listeners whose implementation type is 'script' but which lack a script child, before deployment.","If the listener should not run a script, change the implementation type to class, expression, or delegate-expression instead."],"exampleFix":"// before\nFlowableListener listener = new FlowableListener();\nlistener.setEvent(\"create\");\nlistener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_SCRIPT);\n// after\nFlowableListener listener = new FlowableListener();\nlistener.setEvent(\"create\");\nlistener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_SCRIPT);\nlistener.setScriptInfo(new ScriptInfo(\"javascript\", \"println('hi')\", null));","handlingStrategy":"validation","validationCode":"if (listener.getImplementationType().equals(ImplementationType.IMPLEMENTATION_TYPE_SCRIPT)\n        && (listener.getScriptInfo() == null\n            || listener.getScriptInfo().getScript() == null)) {\n    throw new IllegalArgumentException(\"script task listener requires scriptInfo with script text\");\n}","typeGuard":"boolean hasScriptInfo = l != null\n        && ImplementationType.IMPLEMENTATION_TYPE_SCRIPT.equals(l.getImplementationType())\n        && l.getScriptInfo() != null;","tryCatchPattern":"try {\n    deploymentBuilder.deploy();\n} catch (FlowableIllegalStateException e) {\n    if (e.getMessage().contains(\"Missing ScriptInfo\")) {\n        // fix the listener definition before redeploying\n    } else { throw e; }\n}","preventionTips":["Always pair IMPLEMENTATION_TYPE_SCRIPT with a ScriptInfo containing language and script.","Add a unit test that parses all listener definitions before deployment.","Use XSD/validator checks so script-less script listeners are caught at design time."],"tags":["flowable","bpmn","listener","script","missing-scriptinfo"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}