{"record":{"id":"2a85ca07e8d4e96d","repo":"flowable/flowable-engine","slug":"skip-expression-variable-does-not-resolve-to-a-boo","errorCode":null,"errorMessage":"Skip expression variable does not resolve to a boolean. \" + isSkipExpressionEnabled","messagePattern":"Skip expression variable does not resolve to a boolean\\. \" \\+ isSkipExpressionEnabled","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/SkipExpressionUtil.java","lineNumber":74,"sourceCode":"        \n        String skipExpressionEnabledVariable = \"_ACTIVITI_SKIP_EXPRESSION_ENABLED\";\n        Object isSkipExpressionEnabled = execution.getVariable(skipExpressionEnabledVariable);\n\n        if (isSkipExpressionEnabled instanceof Boolean) {\n            return ((Boolean) isSkipExpressionEnabled).booleanValue();\n        }\n\n        skipExpressionEnabledVariable = \"_FLOWABLE_SKIP_EXPRESSION_ENABLED\";\n        isSkipExpressionEnabled = execution.getVariable(skipExpressionEnabledVariable);\n\n        if (isSkipExpressionEnabled == null) {\n            return false;\n\n        } else if (isSkipExpressionEnabled instanceof Boolean) {\n            return ((Boolean) isSkipExpressionEnabled).booleanValue();\n\n        } else {\n            throw new FlowableIllegalArgumentException(\"Skip expression variable does not resolve to a boolean. \" + isSkipExpressionEnabled);\n        }\n    }\n\n    public static boolean shouldSkipFlowElement(String skipExpressionString, String activityId, DelegateExecution execution, CommandContext commandContext) {\n        ExpressionManager expressionManager = CommandContextUtil.getProcessEngineConfiguration(commandContext).getExpressionManager();\n        Expression skipExpression = expressionManager.createExpression(resolveActiveSkipExpression(skipExpressionString, activityId, \n                        execution.getProcessDefinitionId(), commandContext));\n        \n        Object value = skipExpression.getValue(execution);\n\n        if (value instanceof Boolean) {\n            return ((Boolean) value).booleanValue();\n\n        } else {\n            throw new FlowableIllegalArgumentException(\"Skip expression does not resolve to a boolean: \" + skipExpression.getExpressionText());\n        }\n    }\n    ","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/SkipExpressionUtil.java#L56-L92","documentation":"SkipExpressionUtil.checkSkipExpressionVariable throws this FlowableIllegalArgumentException when the value stored under the DynamicBpmnConstants.ENABLE_SKIP_EXPRESSION variable is neither null nor a Boolean. The engine expects the skip-expression toggle to resolve strictly to a boolean.","triggerScenarios":"A process- or tenant-level variable (or dynamic BPMN override) named/served via ENABLE_SKIP_EXPRESSION holds a non-Boolean object (String \"true\", Integer 1, JSON value), and SkipExpressionUtil.isSkipExpressionEnabled evaluates it.","commonSituations":"Setting the variable via process variables with a String value instead of Boolean; dynamic BPMN overrides serializing values as JsonNode/raw types; scripts or REST calls writing \"true\"/1 instead of a real boolean; upgrading Flowable where the check became stricter.","solutions":["Set the variable as a Boolean: runtimeService.setVariable(executionId, \"_FLOWABLE_SKIP_EXPRESSION_ENABLED\", Boolean.TRUE).","If the value comes from REST/JSON, parse it to Boolean before storing.","If a String is unavoidable, evaluate it yourself and store the Boolean result, or remove the variable so the null branch (disabled) is used.","Search dynamic BPMN override JSON for ENABLE_SKIP_EXPRESSION and correct its type to boolean."],"exampleFix":"// before\nvars.put(\"_FLOWABLE_SKIP_EXPRESSION_ENABLED\", \"true\");\n\n// after\nvars.put(\"_FLOWABLE_SKIP_EXPRESSION_ENABLED\", Boolean.parseBoolean(\"true\"));","handlingStrategy":"validation","validationCode":"Object v = runtimeService.getVariable(executionId, \"_FLOWABLE_SKIP_EXPRESSION_ENABLED\");\nif (v != null && !(v instanceof Boolean)) {\n    runtimeService.setVariable(executionId, \"_FLOWABLE_SKIP_EXPRESSION_ENABLED\",\n            Boolean.parseBoolean(String.valueOf(v)));\n}","typeGuard":"static boolean isSkipToggleValid(Object v) {\n    return v == null || v instanceof Boolean;\n}","tryCatchPattern":"try {\n    SkipExpressionUtil.isSkipExpressionEnabled(...);\n} catch (FlowableIllegalArgumentException e) {\n    // treat as disabled and continue\n}","preventionTips":["Always store the skip toggle as java.lang.Boolean.","Validate types of variables written from REST/scripts before persisting.","Search dynamic BPMN override JSON for non-boolean ENABLE_SKIP_EXPRESSION values."],"tags":["flowable","bpmn","skip-expression","type-mismatch","variable"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}