{"record":{"id":"e853be6cfcd6a585","repo":"flowable/flowable-engine","slug":"pre-upgrade-script-can-t-be-set-when-another-pre-u","errorCode":null,"errorMessage":"Pre upgrade script can't be set when another pre-upgrade task was already specified.","messagePattern":"Pre upgrade script can't be set when another pre-upgrade task was already specified\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentImpl.java","lineNumber":93,"sourceCode":"        this.migrateToProcessDefinitionKey = processDefinitionKey;\n        this.migrateToProcessDefinitionVersion = processDefinitionVersion;\n    }\n\n    public void setMigrateToProcessDefinition(String processDefinitionKey, Integer processDefinitionVersion, String processDefinitionTenantId) {\n        this.migrateToProcessDefinitionKey = processDefinitionKey;\n        this.migrateToProcessDefinitionVersion = processDefinitionVersion;\n        this.migrateToProcessDefinitionTenantId = processDefinitionTenantId;\n    }\n\n    public void setPreUpgradeScript(Script script) {\n        if (this.preUpgradeJavaDelegate == null && this.preUpgradeJavaDelegateExpression == null) {\n            if (script != null) {\n                this.preUpgradeScript = script;\n            } else {\n                throw new IllegalArgumentException(\"Pre upgrade script can't be null.\");\n            }\n        } else {\n            throw new IllegalArgumentException(\"Pre upgrade script can't be set when another pre-upgrade task was already specified.\");\n        }\n    }\n\n    public void setPreUpgradeJavaDelegate(String javaDelegateClassName) {\n        if (this.preUpgradeScript == null && this.preUpgradeJavaDelegateExpression == null) {\n            if (StringUtils.isNotEmpty(javaDelegateClassName)) {\n                this.preUpgradeJavaDelegate = javaDelegateClassName;\n            } else {\n                throw new IllegalArgumentException(\"Pre upgrade java delegate can't be empty or null.\");\n            }\n        } else {\n            throw new IllegalArgumentException(\"Pre upgrade java delegate can't be set when another pre-upgrade task was already specified.\");\n        }\n    }\n\n    public void setPreUpgradeJavaDelegateExpression(String expression) {\n        if (this.preUpgradeScript == null && this.preUpgradeJavaDelegate == null) {\n            if (StringUtils.isNotEmpty(expression)) {","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentImpl.java#L75-L111","documentation":"Only one pre-upgrade task may be configured per migration document. If a pre-upgrade Java delegate or delegate expression was already set, calling setPreUpgradeScript throws IllegalArgumentException because scripts and delegates are mutually exclusive.","triggerScenarios":"Calling setPreUpgradeScript after setPreUpgradeJavaDelegate or setPreUpgradeJavaDelegateExpression on the same ProcessInstanceMigrationDocumentImpl.","commonSituations":"Combining settings from multiple config sources (JSON plus programmatic overrides); copy-paste code that sets both script and delegate; iterating over several upgrade definitions that each call a different setter on one shared document.","solutions":["Choose exactly one pre-upgrade task: script, Java delegate class, or delegate expression","Remove the earlier setPreUpgradeJavaDelegate/setPreUpgradeJavaDelegateExpression call if the script is intended","Create separate ProcessInstanceMigrationDocument instances for unrelated configurations"],"exampleFix":"// before\ndocument.setPreUpgradeJavaDelegate(\"com.acme.PreUpgrader\");\ndocument.setPreUpgradeScript(script);\n// after\ndocument.setPreUpgradeScript(script); // drop the conflicting delegate","handlingStrategy":"validation","validationCode":"if (doc != null && (preDelegateSet || preExpressionSet)) {\n    throw new IllegalStateException(\"Pre-upgrade task already set; script is mutually exclusive\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    document.setPreUpgradeScript(script);\n} catch (IllegalArgumentException e) {\n    log.error(\"Conflicting pre-upgrade configuration: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Decide the single pre-upgrade mechanism (script vs delegate vs expression) up front","Avoid merging migration config from multiple sources onto one document","Track which pre-upgrade setter has been called in your builder wrapper"],"tags":["flowable","process-migration","conflict","pre-upgrade"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}