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
- Ensure the value variable is initialized to an empty collection before DMN evaluation rather than left null.
- Add a null check in the expression: ${value != null && contains(collection, allOf(value))}.
- Make the producer of the value collection return Collections.emptyList() for the absent case.
- Validate input payloads so required list fields are present before invoking the rule task.
- 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
- Initialize the value/elements variable to an empty collection if absent.
- Note check order: collection null check fires before value check.
- Default producers to Collections.emptyList().
- Validate DMN inputs before rule execution.
- Catch IllegalArgumentException as input-validation failure.
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
- collection cannot be null
- activityId is null
- decision tenantId is null
- decisionDefinitionId is null
- decisionKey is null
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)