{"record":{"id":"b5b3bee789186d6f","repo":"flowable/flowable-engine","slug":"only-string-values-can-be-used-with-equals-ignore-b5b3be","errorCode":null,"errorMessage":"Only string values can be used with 'equals ignore case' condition","messagePattern":"Only string values can be used with 'equals ignore case' condition","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/AbstractVariableQueryImpl.java","lineNumber":188,"sourceCode":"    private void addVariable(String name, Object value, QueryOperator operator, boolean localScope) {\n        if (name == null) {\n            throw new ActivitiIllegalArgumentException(\"name is null\");\n        }\n        if (value == null || isBoolean(value)) {\n            // Null-values and booleans can only be used in EQUALS and NOT_EQUALS\n            switch (operator) {\n                case GREATER_THAN:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'greater than' condition\");\n                case LESS_THAN:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'less than' condition\");\n                case GREATER_THAN_OR_EQUAL:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'greater than or equal' condition\");\n                case LESS_THAN_OR_EQUAL:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'less than or equal' condition\");\n            }\n\n            if (operator == QueryOperator.EQUALS_IGNORE_CASE && !(value instanceof String)) {\n                throw new ActivitiIllegalArgumentException(\"Only string values can be used with 'equals ignore case' condition\");\n            }\n\n            if (operator == QueryOperator.NOT_EQUALS_IGNORE_CASE && !(value instanceof String)) {\n                throw new ActivitiIllegalArgumentException(\"Only string values can be used with 'not equals ignore case' condition\");\n            }\n\n            if ((operator == QueryOperator.LIKE || operator == QueryOperator.LIKE_IGNORE_CASE) && !(value instanceof String)) {\n                throw new ActivitiIllegalArgumentException(\"Only string values can be used with 'like' condition\");\n            }\n        }\n        queryVariableValues.add(new QueryVariableValue(name, value, operator, localScope));\n    }\n\n    private boolean isBoolean(Object value) {\n        if (value == null) {\n            return false;\n        }\n        return Boolean.class.isAssignableFrom(value.getClass()) || boolean.class.isAssignableFrom(value.getClass());","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/AbstractVariableQueryImpl.java#L170-L206","documentation":"ActivitiIllegalArgumentException thrown by addVariable when an EQUALS_IGNORE_CASE condition receives a non-String value. Case-insensitive equality is defined only for strings (the engine lowercases the value), so numbers, dates, booleans (and null, handled earlier) are rejected at query-build time.","triggerScenarios":"Calling variableValueEqualsIgnoreCase(name, 42), variableValueEqualsIgnoreCase(name, someDate), or a generic wrapper passing an Object into the ignore-case method.","commonSituations":"Dynamic query builders accept untyped filter values (JSON numbers, dates parsed from request payloads) and route them into string-only operators; a variable changed from numeric to String and code was 'fixed' by switching to ignore-case matching.","solutions":["Convert the value to a String first (String.valueOf(value)) if case-insensitive text matching is intended.","Use plain variableValueEquals for non-string types so type-aware comparison is used.","Validate that filter inputs destined for ignore-case methods are Strings before calling."],"exampleFix":"// before\nquery.taskVariableValueEqualsIgnoreCase(\"orderNumber\", orderId); // Long\n// after\nquery.taskVariableValueEqualsIgnoreCase(\"orderNumber\", String.valueOf(orderId));","handlingStrategy":"type-guard","validationCode":"if (value instanceof String) {\n    query.taskVariableValueEqualsIgnoreCase(name, (String) value);\n} else if (value != null) {\n    query.taskVariableValueEquals(name, value);\n}","typeGuard":"boolean isString(Object o) { return o instanceof String; }","tryCatchPattern":"try {\n    query.taskVariableValueEqualsIgnoreCase(name, value);\n} catch (ActivitiIllegalArgumentException e) {\n    log.warn(\"Ignore-case filter requires a String: {}\", e.getMessage());\n}","preventionTips":["Dispatch string values to ignore-case methods and others to plain equals","Convert non-string inputs with String.valueOf only when text matching is intended","Document that *IgnoreCase methods are String-only in query helper APIs"],"tags":["activiti","query","type-mismatch","string"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}