flowable/flowable-engine · error · IllegalArgumentException

Post upgrade script can't be null.

Error message

Post upgrade script can't be null.

What it means

Flowable's ProcessInstanceMigrationDocument rejects a null post-upgrade Script. When building a migration document, calling setPostUpgradeScript to define a script executed after instance migration requires a non-null Script instance; the setter explicitly throws IllegalArgumentException otherwise, so a requested post-upgrade task is never silently ignored.

Solutions

  1. Ensure the Script instance is constructed before calling setPostUpgradeScript (e.g. new ScriptImpl(...)).
  2. If no post-upgrade work is needed, do not call the setter at all instead of passing null.
  3. If a delegate is more appropriate, use setPostUpgradeJavaDelegate or setPostUpgradeJavaDelegateExpression instead.

Example fix

// before
Script script = maybeGetScript(); // may return null
document.setPostUpgradeScript(script);

// after
Script script = maybeGetScript();
if (script != null) {
    document.setPostUpgradeScript(script);
}
Defensive patterns

Strategy: validation

Validate before calling

if (script == null) { throw new IllegalArgumentException("script must be set before setPostUpgradeScript"); }

Type guard

boolean isValidScript(Script s) { return s != null; }

Try / catch

try {
    document.setPostUpgradeScript(script);
} catch (IllegalArgumentException e) {
    logger.error("Invalid post-upgrade script configuration", e);
}

Prevention

When it happens

Trigger: Calling ProcessInstanceMigrationDocument.setPostUpgradeScript(script) with script == null while no postUpgradeJavaDelegate or postUpgradeJavaDelegateExpression has been set yet (i.e. via the builder's build path that routes to this setter).

Common situations: Conditionally building a Script (e.g. from optional config) and passing the null result; deserializing a migration document where the script element was absent; copy-pasting builder code and forgetting to instantiate the Script object.

Related errors


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

Appendix: source

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

    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)) {
                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.");
        }
    }

View on GitHub (pinned to d6d39ce1c6)