flowable/flowable-engine · error · FlowableIllegalArgumentException

Model value should be a String

Error message

Model value should be a String

What it means

EnumFormType represents a form property with a fixed set of allowed values. convertModelValueToFormValue requires the model value to be a Java String; any other type is rejected with FlowableIllegalArgumentException 'Model value should be a String'. After the type check it also validates the value is one of the configured enum values.

Solutions

  1. Set the variable as a String matching one of the enum form values (e.g. myJavaEnum.name()).
  2. Convert non-string keys at the boundary: String.valueOf or a lookup map from code to key.
  3. Change the form type in the BPMN if numeric codes are intended.
  4. Add a conversion step in custom form rendering before FormService calls.

Example fix

// before
runtimeService.setVariable(executionId, "priority", 3); // Integer
// after
runtimeService.setVariable(executionId, "priority", Priority.fromCode(3).name()); // String key
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = runtimeService.getVariable(executionId, name);
if (v != null && !(v instanceof String)) {
    throw new IllegalArgumentException("Enum form variable '" + name + "' must be a String key");
}

Type guard

static boolean isEnumFormValue(Object v) {
    return v == null || v instanceof String;
}

Try / catch

try {
    formService.submitTaskFormData(taskId, properties);
} catch (FlowableIllegalArgumentException e) {
    if ("Model value should be a String".equals(e.getMessage())) {
        properties.put(enumField, String.valueOf(rawValues.get(enumField)));
        formService.submitTaskFormData(taskId, properties);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Rendering/submitting a form where the variable bound to an enum form property is a non-String type (e.g. Integer code, custom enum object, Long) instead of the String key of the enum value.

Common situations: Storing enum keys as integers from external systems, mapping a Java enum directly into the variable without .name(), refactor that changed the variable type.

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/4f0128d481b01064. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/form/EnumFormType.java:57

    @Override
    public Object getInformation(String key) {
        if ("values".equals(key)) {
            return values;
        }
        return null;
    }

    @Override
    public Object convertFormValueToModelValue(String propertyValue) {
        validateValue(propertyValue);
        return propertyValue;
    }

    @Override
    public String convertModelValueToFormValue(Object modelValue) {
        if (modelValue != null) {
            if (!(modelValue instanceof String)) {
                throw new FlowableIllegalArgumentException("Model value should be a String");
            }
            validateValue((String) modelValue);
        }
        return (String) modelValue;
    }

    protected void validateValue(String value) {
        if (value != null) {
            if (values != null && !values.containsKey(value)) {
                throw new FlowableIllegalArgumentException("Invalid value for enum form property: " + value);
            }
        }
    }

}

View on GitHub (pinned to d6d39ce1c6)