flowable/flowable-engine · error · IllegalArgumentException

Post upgrade expression can't be set when another…

Error message

Post upgrade expression can't be set when another post-upgrade task was already specified.

What it means

The post-upgrade task is exclusive: once a Script or Java delegate class is already set, calling setPostUpgradeJavaDelegateExpression throws IllegalArgumentException so only one post-upgrade mechanism exists on the migration document.

Solutions

  1. Set exactly one of script / delegate / delegate-expression per document.
  2. Check existing values via getters before calling the setter.
  3. Build a fresh migration document for each distinct configuration.

Example fix

// before
document.setPostUpgradeJavaDelegate("com.acme.FixDelegate");
document.setPostUpgradeJavaDelegateExpression("${fixBean}");

// after
document.setPostUpgradeJavaDelegate("com.acme.FixDelegate"); // single task only
Defensive patterns

Strategy: validation

Validate before calling

if (document.getPostUpgradeScript() != null || document.getPostUpgradeJavaDelegate() != null) { throw new IllegalStateException("post-upgrade task already set"); }

Try / catch

try {
    document.setPostUpgradeJavaDelegateExpression(expr);
} catch (IllegalArgumentException e) {
    logger.warn("Another post-upgrade task already configured", e);
}

Prevention

When it happens

Trigger: Calling setPostUpgradeJavaDelegateExpression(expression) after setPostUpgradeScript or setPostUpgradeJavaDelegate has already been called on the same migration document.

Common situations: Multiple configuration layers each choosing a different post-upgrade mechanism; reusing a partially built migration document across different migrations.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

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

    public void setPostUpgradeJavaDelegateExpression(String expression) {
        if (this.postUpgradeScript == null && this.postUpgradeJavaDelegate == null) {
            if (StringUtils.isNotEmpty(expression)) {
                this.postUpgradeJavaDelegateExpression = expression;
            } else {
                throw new IllegalArgumentException("Post upgrade expression can't be empty or null.");
            }
        } else {
            throw new IllegalArgumentException("Post upgrade expression can't be set when another post-upgrade task was already specified.");
        }
    }

    @Override
    public String getMigrateToProcessDefinitionId() {
        return migrateToProcessDefinitionId;
    }

    @Override
    public String getMigrateToProcessDefinitionKey() {
        return migrateToProcessDefinitionKey;
    }

    @Override
    public Integer getMigrateToProcessDefinitionVersion() {
        return migrateToProcessDefinitionVersion;
    }

View on GitHub (pinned to d6d39ce1c6)