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

  1. Add a 'type' field with a registered variable type name such as 'integer', 'string', 'boolean', 'long', 'date', 'serializable' to each variable value node
  2. Validate the JSON before creating the batch config
  3. 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

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


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