{"record":{"id":"c25803f9993546b3","repo":"flowable/flowable-engine","slug":"the-variable-value-does-not-have-a-type-c25803","errorCode":null,"errorMessage":"The variable value does not have a type","messagePattern":"The variable value does not have a type","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/delete/BatchDeleteProcessConfig.java","lineNumber":405,"sourceCode":"                        query.variableNotExists(variableName);\n                        break;\n                    case NOT_EQUALS_IGNORE_CASE:\n                        //Not exposed on the public API\n                        //query.variableValueNotEqualsIgnoreCase(variableName, (String) extractVariableValue(variableValue, engineConfiguration));\n                        //break\n                    default:\n                        throw new FlowableIllegalArgumentException(\"Operator \" + operator + \" is not supported for the variable value\");\n                }\n            }\n\n        }\n\n    }\n\n    protected static Object extractVariableValue(JsonNode variableValueNode, ProcessEngineConfigurationImpl engineConfiguration) {\n        String type = variableValueNode.path(\"type\").stringValue(null);\n        if (type == null) {\n            throw new FlowableIllegalArgumentException(\"The variable value does not have a type\");\n        }\n\n        VariableType variableType = engineConfiguration.getVariableTypes()\n                .getVariableType(type);\n        return variableType.getValue(new VariableValueJsonNodeValueFields(variableValueNode));\n    }\n\n    protected static List<String> asStringList(JsonNode node) {\n        if (node != null && node.isArray() && !node.isEmpty()) {\n            List<String> values = new ArrayList<>(node.size());\n            for (JsonNode element : node) {\n                values.add(element.stringValue());\n            }\n            return values;\n        }\n\n        return null;\n    }","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/delete/BatchDeleteProcessConfig.java#L387-L423","documentation":"extractVariableValue resolves the concrete value of a query variable by looking up its 'type' among the engine's configured VariableTypes. If the variableValue JSON node has no 'type' field, the value cannot be deserialized and this FlowableIllegalArgumentException is thrown.","triggerScenarios":"A variableValue object in the batch configuration's variableValues array lacking the 'type' key, e.g. { \"name\": \"amount\", \"operator\": \"EQUALS\", \"value\": 5 }.","commonSituations":"Hand-written or hand-edited batch delete configurations; tooling exporting query variables without type metadata; users assuming the type can be inferred from the value.","solutions":["Add the required \"type\" field matching a registered variable type, e.g. \"string\", \"long\", \"double\", \"date\"","Verify the type name exists in ProcessEngineConfiguration.getVariableTypes()","Generate the batch configuration programmatically from a real HistoricProcessInstanceQuery so type metadata is preserved"],"exampleFix":"// before\n{ \"name\": \"amount\", \"operator\": \"EQUALS\", \"value\": 5 }\n// after\n{ \"name\": \"amount\", \"operator\": \"EQUALS\", \"type\": \"long\", \"value\": 5 }","handlingStrategy":"validation","validationCode":"for (JsonNode var : variableValuesJson) {\n    if (var.path(\"type\").stringValue(null) == null) {\n        throw new IllegalArgumentException(\"variableValue missing type: \" + var);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    config = BatchDeleteProcessConfig.create(partId, engineConfiguration);\n} catch (FlowableIllegalArgumentException e) {\n    logger.error(\"Variable value missing type: \" + e.getMessage());\n}","preventionTips":["Always include \"type\" (string, long, double, boolean, date, json) in variable filters","Confirm the type name is registered in the engine's VariableTypes","Serialize configs from real query objects instead of authoring by hand"],"tags":["batch","query","variables","configuration"],"backgroundTag":"missing-required-config-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}