flowable/flowable-engine · error · ActivitiIllegalArgumentException

Model value is not of type boolean, but of type

Error message

Model value is not of type boolean, but of type ${class}

What it means

Thrown by BooleanFormType.convertModelValueToFormValue when the model value is neither Boolean nor boolean, i.e. a form property declared as 'boolean' receives a non-boolean value when rendering it into the form. The message includes the actual class name. This is an ActivitiIllegalArgumentException from the form-type conversion layer.

Solutions

  1. Set the variable as a genuine Boolean: runtimeService.setVariable(executionId, name, Boolean.TRUE) or pass Boolean in startProcessInstance variables.
  2. Convert String values before assignment: Boolean.parseBoolean(str) (or parse "1"/"0" explicitly).
  3. Check any delegation/script code that writes the variable to ensure it produces Boolean, not String.
  4. If form rendering should accept truthy strings, add a custom FormType instead of reusing the built-in boolean type.

Example fix

// before
variables.put("approved", request.getParameter("approved")); // String
// after
variables.put("approved", Boolean.parseBoolean(request.getParameter("approved")));
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = runtimeService.getVariable(executionId, "approved");
if (!(v instanceof Boolean)) {
    throw new IllegalStateException("approved must be Boolean, got " + (v == null ? "null" : v.getClass()));
}

Type guard

boolean isBooleanModelValue(Object v) {
    return v instanceof Boolean;
}

Try / catch

try {
    formService.getTaskFormData(taskId); // triggers form rendering/conversion
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
    if (e.getMessage().startsWith("Model value is not of type boolean")) {
        runtimeService.setVariable(executionId, "approved", Boolean.parseBoolean(String.valueOf(rawValue)));
    }
}

Prevention

When it happens

Trigger: A form property of type boolean is rendered and the underlying process variable or expression result is e.g. a String "true"/"1", Integer, or null-like wrapper object instead of a java.lang.Boolean.

Common situations: Setting the variable from a REST call or script that sends "true" as a String; mapping DB columns/CSV inputs into variables without conversion; older engine versions where the value was stored as String.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/form/BooleanFormType.java:54

    public Object convertFormValueToModelValue(String propertyValue) {
        if (propertyValue == null || "".equals(propertyValue)) {
            return null;
        }
        return Boolean.valueOf(propertyValue);
    }

    @Override
    public String convertModelValueToFormValue(Object modelValue) {

        if (modelValue == null) {
            return null;
        }

        if (Boolean.class.isAssignableFrom(modelValue.getClass())
                || boolean.class.isAssignableFrom(modelValue.getClass())) {
            return modelValue.toString();
        }
        throw new ActivitiIllegalArgumentException("Model value is not of type boolean, but of type " + modelValue.getClass().getName());
    }
}

View on GitHub (pinned to d6d39ce1c6)