flowable/flowable-engine · error · IllegalArgumentException

value cannot be null

Error message

value cannot be null

What it means

CollectionUtil.allOf also requires the value operand (the elements expected to be contained) to be non-null. Passing a null value makes the 'all elements within collection' predicate undefined, so Flowable throws IllegalArgumentException. Note ordering: the null collection check runs first, so if both are null you get 'collection cannot be null' instead.

Solutions

  1. Ensure the value variable is initialized to an empty collection before DMN evaluation rather than left null.
  2. Add a null check in the expression: ${value != null && contains(collection, allOf(value))}.
  3. Make the producer of the value collection return Collections.emptyList() for the absent case.
  4. Validate input payloads so required list fields are present before invoking the rule task.
  5. Catch IllegalArgumentException in the caller and treat it as a validation failure of the DMN input data.

Example fix

// before
execution.setVariable("requiredSubset", null);
// after
execution.setVariable("requiredSubset", requiredSubset == null ? Collections.emptyList() : requiredSubset);
Defensive patterns

Strategy: validation

Validate before calling

if (required == null) throw new IllegalStateException("required subset must be non-null before allOf");

Type guard

boolean isNonNullCollection(Object c) { return c != null && c instanceof Collection<?>; }

Try / catch

try {
    CollectionUtil.allOf(collection, value);
} catch (IllegalArgumentException e) {
    if ("value cannot be null".equals(e.getMessage())) { /* value operand missing */ }
}

Prevention

When it happens

Trigger: A DMN input entry evaluates contains(collection, allOf(value)) where value — the list/set of elements that must all be present — is null, usually because the variable holding it was never set or a mapping produced null.

Common situations: Required-subset variable missing in the process variables map; a transformation step returning null instead of an empty list; DMN hit policy input where the 'value' column expression references an undefined variable.

Related errors


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

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/el/util/CollectionUtil.java:39

/**
 * @author Yvo Swillens
 */
public class CollectionUtil {

    /**
     * all values of value must be in collection
     *
     * @return {@code true} if all elements of value are within the collection,
     * {@code false} if at least one element of value is not within the collection
     */
    public static boolean allOf(Object collection, Object value) {

        if (collection == null) {
            throw new IllegalArgumentException("collection cannot be null");
        }

        if (value == null) {
            throw new IllegalArgumentException("value cannot be null");
        }

        // collection to check against
        Collection targetCollection = getTargetCollection(collection, value);

        // elements to check
        if (DMNParseUtil.isParseableCollection(value)) {
            Collection valueCollection = DMNParseUtil.parseCollection(value, targetCollection);
            return valueCollection != null && targetCollection.containsAll(valueCollection);
        } else if (DMNParseUtil.isJavaCollection(value)) {
            return targetCollection.containsAll((Collection) value);
        } else if (DMNParseUtil.isArrayNode(value)) {
            Collection valueCollection = DMNParseUtil.getCollectionFromArrayNode(JsonUtil.asFlowableArrayNode(value));
            return valueCollection != null && targetCollection.containsAll(valueCollection);
        } else {
            Object formattedValue = DMNParseUtil.getFormattedValue(value, targetCollection);
            return targetCollection.contains(formattedValue);
        }

View on GitHub (pinned to d6d39ce1c6)