flowable/flowable-engine · error · ActivitiIllegalArgumentException

Incompatible type set on field declaration '%s' for class %s

Error message

Incompatible type set on field declaration '%s' for class %s. Declared value has type %s, while expecting %s

What it means

Thrown when the value injected via a BPMN field declaration has a Java type incompatible with the declared field on the delegate class. fieldTypeCompatible() fails and the engine refuses to set the field with ActivitiIllegalArgumentException, reporting both types.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegateUtil.java:69

        if (setterMethod != null) {
            try {
                setterMethod.invoke(target, declaration.getValue());
            } catch (IllegalArgumentException e) {
                throw new ActivitiException("Error while invoking '" + declaration.getName() + "' on class " + target.getClass().getName(), e);
            } catch (IllegalAccessException e) {
                throw new ActivitiException("Illegal access when calling '" + declaration.getName() + "' on class " + target.getClass().getName(), e);
            } catch (InvocationTargetException e) {
                throw new ActivitiException("Exception while invoking '" + declaration.getName() + "' on class " + target.getClass().getName(), e);
            }
        } else {
            Field field = ReflectUtil.getField(declaration.getName(), target);
            if (field == null) {
                throw new ActivitiIllegalArgumentException("Field definition uses unexisting field '" + declaration.getName() + "' on class " + target.getClass().getName());
            }
            // Check if the delegate field's type is correct
            if (!fieldTypeCompatible(declaration, field)) {
                throw new ActivitiIllegalArgumentException("Incompatible type set on field declaration '" + declaration.getName()
                        + "' for class " + target.getClass().getName()
                        + ". Declared value has type " + declaration.getValue().getClass().getName()
                        + ", while expecting " + field.getType().getName());
            }
            ReflectUtil.setField(field, target, declaration.getValue());
        }
    }

    public static boolean fieldTypeCompatible(FieldDeclaration declaration, Field field) {
        if (declaration.getValue() != null) {
            return field.getType().isAssignableFrom(declaration.getValue().getClass());
        } else {
            // Null can be set any field type
            return true;
        }
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Make the injected value's type match the field type (e.g. use flowable:string for String fields, numeric literal for int)
  2. Change the delegate field type to accept the value being injected (e.g. String field, parse later)
  3. Use an expression that evaluates to the field's declared type
  4. If injection happens via setter, convert inside the setter

Example fix

// before
<flowable:field name="retryCount" stringValue="3"/> <!-- int field, String value -->
// after
<flowable:field name="retryCount"><flowable:value>3</flowable:value></flowable:field>
Defensive patterns

Strategy: validation

Validate before calling

java.lang.reflect.Field f = delegateClass.getDeclaredField("retryCount");
Object injected = "3";
if (!f.getType().isInstance(injected) && !(injected instanceof String)) throw new IllegalStateException("type mismatch for " + f.getName());

Prevention

When it happens

Trigger: A flowable:field supplies e.g. a String or expression value where the delegate field's type is incompatible (e.g. int field given a non-numeric String, or a String value into a custom object field), and no converter matches.

Common situations: Injecting stringValue into a numeric/boolean field without a matching type; using expression results whose runtime type differs from the field type; changing a field's type in the delegate after processes were deployed.

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/38b64e7fb011fbd1. Report an issue: GitHub.