{"record":{"id":"b53bbf6c067eac2f","repo":"flowable/flowable-engine","slug":"priority-expression-does-not-resolve-to-a-number-b53bbf","errorCode":null,"errorMessage":"Priority expression does not resolve to a number: + activeTaskPriority","messagePattern":"Priority expression does not resolve to a number: \\+ activeTaskPriority","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/UserTaskActivityBehavior.java","lineNumber":294,"sourceCode":"            }\n        }\n    }\n\n    protected void handlePriority(CreateUserTaskBeforeContext beforeContext, ExpressionManager expressionManager, TaskEntity task, DelegateExecution execution,\n            String activeTaskPriority) {\n        if (StringUtils.isNotEmpty(beforeContext.getPriority())) {\n            final Object priority = expressionManager.createExpression(beforeContext.getPriority()).getValue(execution);\n            if (priority != null) {\n                if (priority instanceof String) {\n                    try {\n                        task.setPriority(Integer.valueOf((String) priority));\n                    } catch (NumberFormatException e) {\n                        throw new FlowableIllegalArgumentException(\"Priority does not resolve to a number: \" + priority, e);\n                    }\n                } else if (priority instanceof Number) {\n                    task.setPriority(((Number) priority).intValue());\n                } else {\n                    throw new FlowableIllegalArgumentException(\"Priority expression does not resolve to a number: \" + activeTaskPriority);\n                }\n            }\n        }\n    }\n\n    protected void handleCategory(CreateUserTaskBeforeContext beforeContext, ExpressionManager expressionManager, TaskEntity task,\n            DelegateExecution execution) {\n        if (StringUtils.isNotEmpty(beforeContext.getCategory())) {\n            String category = null;\n            try {\n                Object categoryValue = expressionManager.createExpression(beforeContext.getCategory()).getValue(execution);\n                if (categoryValue != null) {\n                    category = categoryValue.toString();\n                }\n            } catch (FlowableException e) {\n                category = beforeContext.getCategory();\n                LOGGER.warn(\"property not found in task category expression {}\", e.getMessage());\n            }","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/UserTaskActivityBehavior.java#L276-L312","documentation":"The user task's flowable:priority expression resolved to an object that is neither a String nor a Number, so the engine cannot derive an integer priority. This is the else-branch of handlePriority and throws FlowableIllegalArgumentException. (The message references the local field activeTaskPriority in the source, but the offending value is the resolved expression result.)","triggerScenarios":"flowable:priority expression evaluating to Boolean, Map, custom object, or null-adjacent wrapper that is not Number/String.","commonSituations":"Spring bean method returning a Priority enum or custom DTO; expression returning a Boolean flag mistakenly used as priority; variable set to JSON-serialized object by a preceding service task.","solutions":["Make the expression return a Number (Integer) directly, e.g. ${bean.priorityValue} returning int","Unwrap the enum/DTO: return the numeric field instead of the object","Coerce in a delegate/execution listener: setVariable to an Integer before the user task","Fix the type of the underlying process variable"],"exampleFix":"// before\npublic Priority getPriority() { return Priority.HIGH; }\n// after\npublic int getPriority() { return 100; }","handlingStrategy":"type-guard","validationCode":"Object p = priorityExpr.getValue(execution);\nif (p != null && !(p instanceof Number) && !(p instanceof String)) {\n    throw new IllegalArgumentException(\"Priority must be Number or numeric String, got \" + p.getClass());\n}","typeGuard":"boolean isNumericPriority(Object v) {\n    return v instanceof Number || (v instanceof String && ((String) v).matches(\"\\\\d+\"));\n}","tryCatchPattern":"try {\n    taskService.complete(taskId, vars);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"Priority expression\")) {\n        // unwrap the object to its numeric value and retry\n    }\n}","preventionTips":["Return int/Integer from beans used in priority expressions","Never return enums/DTOs/booleans for priority","Normalize variables via an execution listener before the user task","Keep a single documented type for priority variables"],"tags":["user-task","priority","expression","type-mismatch"],"backgroundTag":"type-mismatch","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"}