{"id":"3198d339ab3bea2a","repo":"spring-projects/spring-framework","slug":"target-class-target-getclass-getname-not","errorCode":null,"errorMessage":"Target class [${target.getClass().getName()}] not assignable to editable class [${editable.getName()}]","messagePattern":"Target class \\[(.+?)\\] not assignable to editable class \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/BeanUtils.java","lineNumber":805,"sourceCode":"\t * when matching properties in the source and target objects. See the\n\t * documentation for {@link #copyProperties(Object, Object)} for details.\n\t * @param source the source bean\n\t * @param target the target bean\n\t * @param editable the class (or interface) to restrict property setting to\n\t * @param ignoreProperties array of property names to ignore\n\t * @throws BeansException if the copying failed\n\t * @see BeanWrapper\n\t */\n\tprivate static void copyProperties(Object source, Object target, @Nullable Class<?> editable,\n\t\t\tString @Nullable ... ignoreProperties) throws BeansException {\n\n\t\tAssert.notNull(source, \"Source must not be null\");\n\t\tAssert.notNull(target, \"Target must not be null\");\n\n\t\tClass<?> actualEditable = target.getClass();\n\t\tif (editable != null) {\n\t\t\tif (!editable.isInstance(target)) {\n\t\t\t\tthrow new IllegalArgumentException(\"Target class [\" + target.getClass().getName() +\n\t\t\t\t\t\t\"] not assignable to editable class [\" + editable.getName() + \"]\");\n\t\t\t}\n\t\t\tactualEditable = editable;\n\t\t}\n\t\tPropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);\n\t\tSet<String> ignoredProps = (ignoreProperties != null ? new HashSet<>(Arrays.asList(ignoreProperties)) : null);\n\t\tCachedIntrospectionResults sourceResults = (actualEditable != source.getClass() ?\n\t\t\t\tCachedIntrospectionResults.forClass(source.getClass()) : null);\n\n\t\tfor (PropertyDescriptor targetPd : targetPds) {\n\t\t\tMethod writeMethod = targetPd.getWriteMethod();\n\t\t\tif (writeMethod != null && (ignoredProps == null || !ignoredProps.contains(targetPd.getName()))) {\n\t\t\t\tPropertyDescriptor sourcePd = (sourceResults != null ?\n\t\t\t\t\t\tsourceResults.getPropertyDescriptor(targetPd.getName()) : targetPd);\n\t\t\t\tif (sourcePd != null) {\n\t\t\t\t\tMethod readMethod = sourcePd.getReadMethod();\n\t\t\t\t\tif (readMethod != null) {\n\t\t\t\t\t\tif (isAssignable(writeMethod, readMethod, sourcePd, targetPd)) {","sourceCodeStart":787,"sourceCodeEnd":823,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java#L787-L823","documentation":"Thrown as IllegalArgumentException by the private copyProperties(source, target, editable, ignoreProperties) when an 'editable' filter class is provided but the target object is not an instance of it (BeanUtils.java:803-807). The editable class is meant to restrict which properties are copied, and Spring asserts target assignability up front.","triggerScenarios":"Calling BeanUtils.copyProperties(src, target, SomeClass.class) (or the variant with ignore-properties) where !SomeClass.class.isInstance(target). Exposed via BeanUtils.copyProperties(source, target, editable) and copyProperties(source, target, editable, ignoreProperties).","commonSituations":"Passing the source's class instead of the target's class as the editable filter; passing an interface the target does not implement; target being a proxy (CGLIB/JDK) whose runtime class differs; copying between unrelated DTOs while passing a third type as the filter.","solutions":["Pass an editable class that the target actually implements/extends (commonly target.getClass() or a shared interface of target).","If you do not need filtering, call copyProperties(source, target) without the editable argument.","For proxies, pass the user class / interface rather than the synthetic proxy class, or unwrap the proxy first.","Double-check argument order: copyProperties(source, target, editable) — editable applies to target, not source."],"exampleFix":"// before\nBeanUtils.copyProperties(dto, entity, Dto.class); // entity not a Dto\n\n// after\nBeanUtils.copyProperties(dto, entity, Entity.class);\n// or simply: BeanUtils.copyProperties(dto, entity);","handlingStrategy":"validation","validationCode":"if (editable != null && !editable.isInstance(target)) {\n  throw new IllegalArgumentException(\n    \"target \" + target.getClass() + \" not instance of editable \" + editable);\n}","typeGuard":"public static boolean editableMatches(Class<?> editable, Object target) {\n  return editable == null || editable.isInstance(target);\n}","tryCatchPattern":"try { BeanUtils.copyProperties(src, target, editable); }\ncatch (IllegalArgumentException e) {\n  BeanUtils.copyProperties(src, target); // retry without the editable filter\n}","preventionTips":["Pass an editable class the target implements/extends (or omit it).","Mind argument order: copyProperties(source, target, editable) — editable applies to target.","Unwrap proxies before copying, or pass the user interface as editable."],"tags":["spring-beans","beanutils","copy-properties","assignable","editable"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}