{"id":"2384f843c15252e1","repo":"spring-projects/spring-framework","slug":"invalid-method-signature-unable-to-resolve-type","errorCode":null,"errorMessage":"Invalid method signature: unable to resolve type [${parameterTypeName}] for argument ${i}. Root cause: ${ex}","messagePattern":"Invalid method signature: unable to resolve type \\[(.+?)\\] for argument (.+?)\\. Root cause: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/BeanUtils.java","lineNumber":479,"sourceCode":"\t\telse if (startParen == -1 && endParen > -1) {\n\t\t\tthrow new IllegalArgumentException(\"Invalid method signature '\" + signature +\n\t\t\t\t\t\"': expected opening '(' for args list\");\n\t\t}\n\t\telse if (startParen == -1) {\n\t\t\treturn findMethodWithMinimalParameters(clazz, signature);\n\t\t}\n\t\telse {\n\t\t\tString methodName = signature.substring(0, startParen);\n\t\t\tString[] parameterTypeNames =\n\t\t\t\t\tStringUtils.commaDelimitedListToStringArray(signature.substring(startParen + 1, endParen));\n\t\t\tClass<?>[] parameterTypes = new Class<?>[parameterTypeNames.length];\n\t\t\tfor (int i = 0; i < parameterTypeNames.length; i++) {\n\t\t\t\tString parameterTypeName = parameterTypeNames[i].trim();\n\t\t\t\ttry {\n\t\t\t\t\tparameterTypes[i] = ClassUtils.forName(parameterTypeName, clazz.getClassLoader());\n\t\t\t\t}\n\t\t\t\tcatch (Throwable ex) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Invalid method signature: unable to resolve type [\" +\n\t\t\t\t\t\t\tparameterTypeName + \"] for argument \" + i + \". Root cause: \" + ex);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn findMethod(clazz, methodName, parameterTypes);\n\t\t}\n\t}\n\n\n\t/**\n\t * Retrieve the JavaBeans {@code PropertyDescriptor}s of a given class.\n\t * @param clazz the Class to retrieve the PropertyDescriptors for\n\t * @return an array of {@code PropertyDescriptors} for the given class\n\t * @throws BeansException if PropertyDescriptor look fails\n\t */\n\tpublic static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws BeansException {\n\t\treturn CachedIntrospectionResults.forClass(clazz).getPropertyDescriptors();\n\t}\n","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java#L461-L497","documentation":"Thrown as IllegalArgumentException by resolveSignature when one of the parameter type names inside the argument list cannot be resolved to a Class via ClassUtils.forName using the target class's ClassLoader (BeanUtils.java:473-481). The offending type name, argument index, and root cause are included.","triggerScenarios":"resolveSignature('foo(com.example.Missing, java.lang.String)', clazz) where 'com.example.Missing' is not on the classpath, is misspelled, or the classloader cannot load it. Also triggered by array/notational mistakes like 'String[]' spelled incorrectly or unimported nested classes.","commonSituations":"Refactoring/renaming a class referenced in config without updating the signature string; missing dependency providing the parameter type; using simple names where fully-qualified names are required; nested classes referenced without the enclosing$Inner syntax; multi-module classloader isolation.","solutions":["Use the fully-qualified type name exactly matching a class resolvable by the target class's ClassLoader.","Add the missing type's dependency/artifact to the runtime classpath.","For nested types use 'com.example.Outer$Inner'; for arrays use the JVM notation 'java.lang.String[]' or the canonical form ClassUtils.forName accepts.","After a rename, update all method-signature strings in config and grep for the old name."],"exampleFix":"// before\nresolveSignature(\"process(com.example.OldName)\", clazz); // OldName renamed\n\n// after\nresolveSignature(\"process(com.example.NewName)\", clazz);","handlingStrategy":"validation","validationCode":"String[] parts = sig.substring(sig.indexOf('(')+1, sig.indexOf(')')).split(\",\");\nClassLoader cl = clazz.getClassLoader();\nfor (String t : parts) ClassUtils.forName(t.trim(), cl); // throws early if unresolvable","typeGuard":"public static boolean signatureTypesResolvable(Class<?> c, String sig) {\n  try { BeanUtils.resolveSignature(sig, c); return true; }\n  catch (IllegalArgumentException e) { return false; }\n}","tryCatchPattern":"try { BeanUtils.resolveSignature(sig, clazz); }\ncatch (IllegalArgumentException e) {\n  // message names the unresolvable type; fix config or add the dependency\n}","preventionTips":["Use fully-qualified type names resolvable by the target ClassLoader.","Keep referenced types and their dependencies on the runtime classpath.","Use 'Outer$Inner' for nested classes; update signatures after renames."],"tags":["spring-beans","beanutils","method-signature","type-resolution","classpath"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}