flowable/flowable-engine · error · IllegalArgumentException

Pre upgrade expression can't be set when another…

Error message

Pre upgrade expression can't be set when another pre-upgrade task was already specified.

What it means

Only one pre-upgrade task may be configured. If a pre-upgrade script or Java delegate was already set, calling setPreUpgradeJavaDelegateExpression throws IllegalArgumentException even if the expression itself is valid.

Solutions

  1. Configure exactly one pre-upgrade task per document
  2. Remove the earlier setPreUpgradeScript/setPreUpgradeJavaDelegate call if the expression is intended
  3. Build a fresh document when configuration must change

Example fix

// before
document.setPreUpgradeJavaDelegate("com.acme.PreUpgrader");
document.setPreUpgradeJavaDelegateExpression("${preUpgrader}");
// after
document.setPreUpgradeJavaDelegateExpression("${preUpgrader}");
Defensive patterns

Strategy: validation

Validate before calling

if (doc != null && (preScriptSet || preDelegateSet)) {
    throw new IllegalStateException("Pre-upgrade task already set; expression is mutually exclusive");
}

Try / catch

try {
    document.setPreUpgradeJavaDelegateExpression(expression);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("Conflicting pre-upgrade configuration", e);
}

Prevention

When it happens

Trigger: Calling setPreUpgradeJavaDelegateExpression after setPreUpgradeScript or setPreUpgradeJavaDelegate on the same ProcessInstanceMigrationDocumentImpl.

Common situations: Combining script-based and expression-based upgrade hooks from different sources; sequential builder configuration copied from examples showing each option separately.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentImpl.java:117

            if (StringUtils.isNotEmpty(javaDelegateClassName)) {
                this.preUpgradeJavaDelegate = javaDelegateClassName;
            } else {
                throw new IllegalArgumentException("Pre upgrade java delegate can't be empty or null.");
            }
        } else {
            throw new IllegalArgumentException("Pre upgrade java delegate can't be set when another pre-upgrade task was already specified.");
        }
    }

    public void setPreUpgradeJavaDelegateExpression(String expression) {
        if (this.preUpgradeScript == null && this.preUpgradeJavaDelegate == null) {
            if (StringUtils.isNotEmpty(expression)) {
                this.preUpgradeJavaDelegateExpression = expression;
            } else {
                throw new IllegalArgumentException("Pre upgrade expression can't be empty or null.");
            }
        } else {
            throw new IllegalArgumentException("Pre upgrade expression can't be set when another pre-upgrade task was already specified.");
        }
    }

    public void setPostUpgradeScript(Script script) {
        if (this.postUpgradeJavaDelegate == null && this.postUpgradeJavaDelegateExpression == null) {
            if (script != null) {
                this.postUpgradeScript = script;
            } else {
                throw new IllegalArgumentException("Post upgrade script can't be null.");
            }
        } else {
            throw new IllegalArgumentException("Post upgrade script can't be set when another post-upgrade task was already specified.");
        }
    }

    public void setPostUpgradeJavaDelegate(String javaDelegateClassName) {
        if (this.postUpgradeScript == null && this.postUpgradeJavaDelegateExpression == null) {
            if (StringUtils.isNotEmpty(javaDelegateClassName)) {

View on GitHub (pinned to d6d39ce1c6)