flowable/flowable-engine · error · FlowableException

String value " " is not allowed in boolean expression

Error message

String value "${value}" is not allowed in boolean expression

What it means

ExpressionUtils.parseBoolean converts a resolved field value to a boolean. Strings are only accepted when they equal 'true' or 'false' ignoring case; any other string (e.g. 'yes', '1', 'on', or an expression that failed to resolve to a boolean) triggers this FlowableException. It exists to prevent silently treating arbitrary strings as false.

Solutions

  1. Change the expression/attribute value to literal true or false (string, case-insensitive)
  2. Fix the supplying variable so it contains 'true'/'false' instead of 'yes'/'no'/'1'/'0'
  3. If the value comes from user input, normalize it before the task (e.g. in a listener)
  4. Use a Boolean-typed field/expression instead of a String where supported

Example fix

// before
<flowable:httpTask saveResponseParameters="yes" />
// after
<flowable:httpTask saveResponseParameters="true" />
Defensive patterns

Strategy: validation

Validate before calling

Object v = execution.getVariable("flag");
if (v instanceof String s && !(s.equalsIgnoreCase("true") || s.equalsIgnoreCase("false"))) {
    throw new IllegalArgumentException("flag must be 'true' or 'false'");
}

Type guard

boolean isValidBoolString(Object v) { return v == null || (v instanceof String s && (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("false"))); }

Try / catch

try {
    delegate.execute(execution);
} catch (FlowableException e) {
    if (e.getMessage() != null && e.getMessage().contains("not allowed in boolean expression")) {
        // normalize the variable to true/false and retry once
    } else { throw e; }
}

Prevention

When it happens

Trigger: A boolean-typed HTTP task field (e.g. saveRequestVariablesToResult, saveResponseParameters, or a failStatus/dispatch-related flag) is given a String value other than 'true'/'false', typically via an expression that resolves to text like 'yes' or 'Y'.

Common situations: Configuring task attributes with 'true'/'false' vs 'yes'/'no' conventions from other systems; a variable holding 'True ' with trailing whitespace is fine (equalsIgnoreCase) but 'enabled' is not; locale-specific representations.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-http-common/src/main/java/org/flowable/http/common/impl/ExpressionUtils.java:56

        }
        return 0;
    }

    public static boolean getBooleanFromField(final Expression expression, final VariableContainer execution) {
        if (expression != null) {
            Object value = expression.getValue(execution);
            return parseBoolean(value);
        }
        return false;
    }

    protected static boolean parseBoolean(Object value) {
        if (value != null) {
            if (value instanceof String stringValue) {
                if ("true".equalsIgnoreCase(stringValue) || "false".equalsIgnoreCase(stringValue)) {
                    return Boolean.parseBoolean(value.toString());
                }
                throw new FlowableException("String value \"" + value + "\" is not allowed in boolean expression");
            }
            if (value instanceof Boolean) {
                return (Boolean) value;
            }
            throw new FlowableException("Value \"" + value + "\" can not be converted into boolean");
        }
        return false;
    }

    public static String getStringFromField(final Expression expression, final VariableContainer execution) {
        if (expression != null) {
            Object value = expression.getValue(execution);
            if (value != null) {
                return value.toString();
            }
        }
        return null;
    }

View on GitHub (pinned to d6d39ce1c6)