{"record":{"id":"e43edf23f9565ab8","repo":"flowable/flowable-engine","slug":"cannot-create-script-task-listener-missing-scri","errorCode":null,"errorMessage":"Cannot create 'script' task listener. Missing ScriptInfo.","messagePattern":"Cannot create 'script' task listener\\. Missing ScriptInfo\\.","errorType":"exception","errorClass":"FlowableIllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/listener/DefaultCmmnListenerFactory.java","lineNumber":60,"sourceCode":"    public TaskListener createClassDelegateTaskListener(FlowableListener listener) {\n        return classDelegateFactory.createLifeCycleListener(listener.getImplementation(), listener.getSourceState(), listener.getTargetState(), listener.getFieldExtensions());\n    }\n\n    @Override\n    public TaskListener createExpressionTaskListener(FlowableListener listener) {\n        return new ExpressionTaskListener(expressionManager.createExpression(listener.getImplementation()));\n    }\n\n    @Override\n    public TaskListener createDelegateExpressionTaskListener(FlowableListener listener) {\n        return new DelegateExpressionTaskListener(expressionManager.createExpression(listener.getImplementation()), listener.getFieldExtensions());\n    }\n\n    @Override\n    public TaskListener createScriptTypeTaskListener(FlowableListener listener) {\n        ScriptInfo scriptInfo = listener.getScriptInfo();\n        if (scriptInfo == null) {\n            throw new FlowableIllegalStateException(\"Cannot create 'script' task listener. Missing ScriptInfo.\");\n        }\n        ScriptTypeTaskListener scriptListener = new ScriptTypeTaskListener(createExpression(listener.getScriptInfo().getLanguage()),\n                createExpression(listener.getScriptInfo().getScript()));\n        Optional.ofNullable(listener.getScriptInfo().getResultVariable())\n                .ifPresent(resultVar -> scriptListener.setResultVariable(createExpression(resultVar)));\n        return scriptListener;\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 PlanItemInstanceLifecycleListener createClassDelegateLifeCycleListener(FlowableListener listener) {\n        return classDelegateFactory.create(listener.getImplementation(), listener.getFieldExtensions());\n    }\n\n    @Override","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/listener/DefaultCmmnListenerFactory.java#L42-L78","documentation":"DefaultCmmnListenerFactory builds a ScriptTypeTaskListener from a FlowableListener. A script-type listener must carry a ScriptInfo (language + script); if listener.getScriptInfo() returns null the factory cannot construct the listener and throws FlowableIllegalStateException. This indicates malformed listener definition data — typically a model/parse bug or an incorrectly assembled FlowableListener.","triggerScenarios":"createScriptTypeTaskListener(listener) is called for a listener whose type is script but whose ScriptInfo was never populated (e.g. the CMMN XML listener definition lacked script content, or a programmatically built FlowableListener omitted setScriptInfo).","commonSituations":"Hand-written or dynamically generated CMMN XML with a task listener marked as script but missing <script> details; custom model code building FlowableListener objects without ScriptInfo; parse/upgrade issue where ScriptInfo is dropped.","solutions":["Fix the listener definition so the script element carries both language and script content, then redeploy the case definition.","If building FlowableListener programmatically, call setScriptInfo(ScriptInfo) with non-null language/script before registering the listener.","Validate the deployed case model (parse step) to catch missing ScriptInfo at deploy time instead of runtime.","Check the Flowable version for known parser bugs around script listener metadata if definitions look correct."],"exampleFix":"// before\nFlowableListener listener = new FlowableListenerImpl();\nlistener.setEventType(\"create\");\nlistener.setOnTransactionType(\"before-commit\");\n// after\nFlowableListener listener = new FlowableListenerImpl();\nlistener.setEventType(\"create\");\nScriptInfo scriptInfo = new ScriptInfoImpl(\"javascript\", \"task.setVariable('done', true)\", null);\nlistener.setScriptInfo(scriptInfo);","handlingStrategy":"validation","validationCode":"if (listener.getScriptInfo() == null || listener.getScriptInfo().getScript() == null || listener.getScriptInfo().getLanguage() == null) {\n    throw new IllegalArgumentException(\"Script task listener requires ScriptInfo with language and script\");\n}","typeGuard":"boolean hasScriptInfo(FlowableListener l) {\n    return l.getScriptInfo() != null\n        && l.getScriptInfo().getLanguage() != null\n        && l.getScriptInfo().getScript() != null;\n}","tryCatchPattern":"try {\n    TaskListener tl = listenerFactory.createScriptTypeTaskListener(listener);\n} catch (FlowableIllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Missing ScriptInfo\")) {\n        throw new ModelValidationException(\"Listener definition lacks script info; fix case XML\", e);\n    }\n    throw e;\n}","preventionTips":["Validate CMMN models at deploy time for listener completeness","When building FlowableListener programmatically, always set ScriptInfo","Add schema/XML validation for script listener attributes in CI"],"tags":["flowable","cmmn","task-listener","script","missing-argument"],"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"}