flowable/flowable-engine · error · FlowableIllegalArgumentException
key is null
Error message
key is null
What it means
Flowable's DMN DecisionQueryImpl.decisionKey(String) requires a non-null key because the query is translated into a SQL WHERE clause; a null key cannot be expressed as a condition. Calling decisionKey(null) is treated as a programming error and rejected immediately with FlowableIllegalArgumentException rather than failing later at query execution.
Source
Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/DecisionQueryImpl.java:160
throw new FlowableIllegalArgumentException("ids are null");
}
this.deploymentIds = deploymentIds;
return this;
}
@Override
public DecisionQueryImpl parentDeploymentId(String parentDeploymentId) {
if (parentDeploymentId == null) {
throw new FlowableIllegalArgumentException("parentDeploymentId is null");
}
this.parentDeploymentId = parentDeploymentId;
return this;
}
@Override
public DecisionQueryImpl decisionKey(String key) {
if (key == null) {
throw new FlowableIllegalArgumentException("key is null");
}
this.key = key;
return this;
}
@Override
public DecisionQueryImpl decisionKeyLike(String keyLike) {
if (keyLike == null) {
throw new FlowableIllegalArgumentException("keyLike is null");
}
this.keyLike = keyLike;
return this;
}
@Override
public DecisionQueryImpl decisionResourceName(String resourceName) {
if (resourceName == null) {
throw new FlowableIllegalArgumentException("resourceName is null");View on GitHub (pinned to d6d39ce1c6)
Solutions
- Ensure a non-null decision key before building the query; if the key is optional, skip calling decisionKey entirely.
- Validate or resolve the key (e.g. from config/request) with a default or early return when absent.
- If you need pattern matching with a possibly-null value, guard with `if (key != null) query.decisionKey(key);`
Example fix
// before
DmnDecisionQuery query = dmnRepositoryService.createDecisionQuery().decisionKey(request.getKey());
// after
DmnDecisionQuery query = dmnRepositoryService.createDecisionQuery();
if (request.getKey() != null) {
query.decisionKey(request.getKey());
} Defensive patterns
Strategy: validation
Validate before calling
if (key == null || key.isEmpty()) {
throw new IllegalArgumentException("decision key must be provided");
}
query.decisionKey(key); Type guard
boolean hasKey(String k) { return k != null && !k.isEmpty(); } Try / catch
try {
query.decisionKey(key);
} catch (FlowableIllegalArgumentException e) {
if ("key is null".equals(e.getMessage())) {
// proceed with unfiltered query or rethrow with context
} else { throw e; }
} Prevention
- Never forward optional parameters into query builders unconditionally
- Treat null filters as 'skip the filter', not 'pass null'
- Validate request/config inputs at the boundary before building queries
When it happens
Trigger: Calling decisionTableQuery().decisionKey(null) or decisionQuery().decisionKey(null) — passing a variable that was never initialized, or a method parameter forwarded straight into the query builder.
Common situations: Dynamic query builders where the key comes from a user request, config file, or REST path parameter that is missing/empty; refactors that renamed a deployment key so the lookup variable is null; code that treats null key as 'match all' which Flowable does not support (use no filter or keyLike instead).
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/036c7c7a5dce6383.
Report an issue: GitHub.