{"record":{"id":"212923607e2fc8ed","repo":"flowable/flowable-engine","slug":"error-while-invoking-s-on-class-s-212923","errorCode":null,"errorMessage":"Error while invoking '%s' on class %s","messagePattern":"Error while invoking '(.+?)' on class (.+?)","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegateUtil.java","lineNumber":56,"sourceCode":"    }\n\n    public static void applyFieldDeclaration(List<FieldDeclaration> fieldDeclarations, Object target) {\n        if (fieldDeclarations != null) {\n            for (FieldDeclaration declaration : fieldDeclarations) {\n                applyFieldDeclaration(declaration, target);\n            }\n        }\n    }\n\n    public static void applyFieldDeclaration(FieldDeclaration declaration, Object target) {\n        Method setterMethod = ReflectUtil.getSetter(declaration.getName(),\n                target.getClass(), declaration.getValue().getClass());\n\n        if (setterMethod != null) {\n            try {\n                setterMethod.invoke(target, declaration.getValue());\n            } catch (IllegalArgumentException e) {\n                throw new ActivitiException(\"Error while invoking '\" + declaration.getName() + \"' on class \" + target.getClass().getName(), e);\n            } catch (IllegalAccessException e) {\n                throw new ActivitiException(\"Illegal access when calling '\" + declaration.getName() + \"' on class \" + target.getClass().getName(), e);\n            } catch (InvocationTargetException e) {\n                throw new ActivitiException(\"Exception while invoking '\" + declaration.getName() + \"' on class \" + target.getClass().getName(), e);\n            }\n        } else {\n            Field field = ReflectUtil.getField(declaration.getName(), target);\n            if (field == null) {\n                throw new ActivitiIllegalArgumentException(\"Field definition uses unexisting field '\" + declaration.getName() + \"' on class \" + target.getClass().getName());\n            }\n            // Check if the delegate field's type is correct\n            if (!fieldTypeCompatible(declaration, field)) {\n                throw new ActivitiIllegalArgumentException(\"Incompatible type set on field declaration '\" + declaration.getName()\n                        + \"' for class \" + target.getClass().getName()\n                        + \". Declared value has type \" + declaration.getValue().getClass().getName()\n                        + \", while expecting \" + field.getType().getName());\n            }\n            ReflectUtil.setField(field, target, declaration.getValue());","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegateUtil.java#L38-L74","documentation":"ClassDelegateUtil.applyFieldDeclaration is the shared utility performing the same setter-based injection as ClassDelegate: it invokes the matched setter reflectively and wraps IllegalArgumentException from Method.invoke into an ActivitiException ('Error while invoking ...'). It indicates the declared field value cannot legally be passed to the setter.","triggerScenarios":"A delegate (via ClassDelegateUtil-based helpers) receives a field declaration whose value type is incompatible with the setter's parameter type, making setterMethod.invoke(target, value) throw IllegalArgumentException.","commonSituations":"Same as 4394 but via the utility path: incompatible activiti:field value types (String vs int/Expression/Date), refactored setter signatures, EL expression producing an unexpected runtime type.","solutions":["Match the declared value type to the setter parameter type in the process definition.","Change the setter to accept a compatible type (String/Expression/Object) and convert internally.","Inspect the wrapped cause to pinpoint the parameter conversion failure."],"exampleFix":"// before\npublic void setThreshold(Expression threshold) { ... } // declared value is a plain String\n// after\npublic void setThreshold(Object threshold) {\n  this.threshold = threshold instanceof Expression e ? e : new FixedValue((String) threshold);\n}","handlingStrategy":"validation","validationCode":"Method m = target.getClass().getMethod(\"set\" + capitalize(declaration.getName()), declaration.getValue().getClass());\n// ensure a setter with exactly this parameter type exists before injection","typeGuard":"boolean setterCompatible(Object target, String field, Object value) {\n  try {\n    target.getClass().getMethod(\"set\" + Character.toUpperCase(field.charAt(0)) + field.substring(1), value.getClass());\n    return true;\n  } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n  ClassDelegateUtil.applyFieldDeclaration(declaration, target, throwExceptionOnMissingField);\n} catch (ActivitiException e) {\n  if (e.getMessage().startsWith(\"Error while invoking\")) {\n    log.error(\"Cannot inject field '{}' on {}: type mismatch\", declaration.getName(), target.getClass(), e);\n  } else throw e;\n}","preventionTips":["Keep utility-injected field types aligned with setter parameter types","Prefer Object/Expression setters with internal conversion","Unit-test field injection for every reusable delegate helper"],"tags":["reflection","field-injection","delegate","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}