flowable/flowable-engine · error · FlowableIllegalArgumentException
The variable value does not have a type
Error message
The variable value does not have a type
What it means
Thrown by extractVariableValue() when a variable value node in the query JSON lacks a 'type' field. The type string is required to look up the VariableType in the engine's variable type registry and convert the raw JSON fields into a Java value. Without it, no conversion is possible.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/delete/BatchDeleteCaseConfig.java:383
query.variableNotExists(variableName);
break;
case NOT_EQUALS_IGNORE_CASE:
//Not exposed on the public API
//query.variableValueNotEqualsIgnoreCase(variableName, (String) extractVariableValue(variableValue, engineConfiguration));
//break;
default:
throw new FlowableIllegalArgumentException("Operator " + operator + " is not supported for the variable value");
}
}
}
}
protected static Object extractVariableValue(JsonNode variableValueNode, CmmnEngineConfiguration engineConfiguration) {
String type = variableValueNode.path("type").stringValue(null);
if (type == null) {
throw new FlowableIllegalArgumentException("The variable value does not have a type");
}
VariableType variableType = engineConfiguration.getVariableTypes()
.getVariableType(type);
return variableType.getValue(new VariableValueJsonNodeValueFields(variableValueNode));
}
protected static List<String> asStringList(JsonNode node) {
if (node != null && node.isArray() && !node.isEmpty()) {
List<String> values = new ArrayList<>(node.size());
for (JsonNode element : node) {
values.add(element.stringValue());
}
return values;
}
return null;
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Add a 'type' field with a registered variable type name such as 'integer', 'string', 'boolean', 'long', 'date', 'serializable' to each variable value node
- Validate the JSON before creating the batch config
- Create the batch configuration via the public HistoricCaseInstanceQuery API so types are serialized correctly
Example fix
// before
{"name":"count","operator":"GREATER_THAN","value":5}
// after
{"name":"count","type":"integer","operator":"GREATER_THAN","value":5} Defensive patterns
Strategy: validation
Validate before calling
if (variableValue.path("type").stringValue(null) == null) throw new IllegalArgumentException("variable value missing type");
// also verify the type is registered:
engineConfiguration.getVariableTypes().getVariableType(typeName); // throws if unknown Type guard
boolean hasType(JsonNode n) { return n != null && n.path("type").stringValue(null) != null; } Try / catch
try { createBatch(cmd); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().contains("does not have a type")) { log.error("Add 'type' field to variable value", e); } throw e; } Prevention
- Always include the variable type name in serialized variable values
- Only use type names registered in the engine's VariableTypes registry
- Let the public API serialize variable values instead of hand-writing JSON
When it happens
Trigger: A variableValues entry in the batch configuration JSON omits the 'type' key (e.g. only name/operator/value present), or the type name is misspelled.
Common situations: Hand-authored batch JSON; serializers that omit the type for primitive values; migrations between engines with different variable serialization formats.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- The variable value does not contain an operator value
- Query property ${property} is not supported
- Cannot aggregate overview variable: ${varInstance}
- Cannot aggregate variable: ${varInstance}
- Operator ${operator} is not supported for the variable value
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0c9fcb29f97ff474.
Report an issue: GitHub.