flowable/flowable-engine · error · IllegalArgumentException

Pre upgrade script can't be null.

Error message

Pre upgrade script can't be null.

What it means

ProcessInstanceMigrationDocumentImpl.setPreUpgradeScript enforces that exactly one pre-upgrade task (script, Java delegate, or delegate expression) is configured. When no other pre-upgrade task is set and the provided Script is null, there is nothing to assign, so it throws IllegalArgumentException.

Solutions

  1. Only call setPreUpgradeScript when a non-null Script instance exists
  2. Skip the setter entirely if no pre-upgrade script is needed
  3. Guard the call: if (script != null) document.setPreUpgradeScript(script);

Example fix

// before
document.setPreUpgradeScript(jsonScript); // may be null
// after
if (jsonScript != null) {
    document.setPreUpgradeScript(jsonScript);
}
Defensive patterns

Strategy: validation

Validate before calling

if (script == null) { throw new IllegalArgumentException("preUpgradeScript required"); } document.setPreUpgradeScript(script);

Type guard

boolean canSetPreUpgradeScript(ProcessInstanceMigrationDocumentImpl doc, Script s) {
    return s != null;
}

Try / catch

try {
    document.setPreUpgradeScript(script);
} catch (IllegalArgumentException e) {
    log.warn("No pre-upgrade script configured: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling setPreUpgradeScript(null) on a ProcessInstanceMigrationDocumentImpl — typically from build() when no preUpgradeScript was configured but the setter was invoked unconditionally.

Common situations: Programmatic document assembly that always calls the setter; JSON conversion mapping an absent/empty script element to null; refactoring that removed script construction but left the setter call.

Related errors


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

Appendix: source

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

    }

    public void setMigrateToProcessDefinition(String processDefinitionKey, Integer processDefinitionVersion) {
        this.migrateToProcessDefinitionKey = processDefinitionKey;
        this.migrateToProcessDefinitionVersion = processDefinitionVersion;
    }

    public void setMigrateToProcessDefinition(String processDefinitionKey, Integer processDefinitionVersion, String processDefinitionTenantId) {
        this.migrateToProcessDefinitionKey = processDefinitionKey;
        this.migrateToProcessDefinitionVersion = processDefinitionVersion;
        this.migrateToProcessDefinitionTenantId = processDefinitionTenantId;
    }

    public void setPreUpgradeScript(Script script) {
        if (this.preUpgradeJavaDelegate == null && this.preUpgradeJavaDelegateExpression == null) {
            if (script != null) {
                this.preUpgradeScript = script;
            } else {
                throw new IllegalArgumentException("Pre upgrade script can't be null.");
            }
        } else {
            throw new IllegalArgumentException("Pre upgrade script can't be set when another pre-upgrade task was already specified.");
        }
    }

    public void setPreUpgradeJavaDelegate(String javaDelegateClassName) {
        if (this.preUpgradeScript == null && this.preUpgradeJavaDelegateExpression == null) {
            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.");
        }
    }

View on GitHub (pinned to d6d39ce1c6)