{"record":{"id":"64e8c9b35c36b675","repo":"alibaba/spring-cloud-alibaba","slug":"type-class-attribute-exists-but-type-method-at","errorCode":null,"errorMessage":"{type} class attribute exists but {type} method attribute is not exists in bean[{beanName}]","messagePattern":"(.+?) class attribute exists but (.+?) method attribute is not exists in bean\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelBeanPostProcessor.java","lineNumber":117,"sourceCode":"\t\t\t\tSentinelConstants.BLOCK_TYPE);\n\t\tcheckBlock4RestTemplate(sentinelRestTemplate.fallbackClass(),\n\t\t\t\tsentinelRestTemplate.fallback(), beanName,\n\t\t\t\tSentinelConstants.FALLBACK_TYPE);\n\t\tcheckBlock4RestTemplate(sentinelRestTemplate.urlCleanerClass(),\n\t\t\t\tsentinelRestTemplate.urlCleaner(), beanName,\n\t\t\t\tSentinelConstants.URLCLEANER_TYPE);\n\t}\n\n\tprivate void checkBlock4RestTemplate(Class<?> blockClass, String blockMethod,\n\t\t\tString beanName, String type) {\n\t\tif (blockClass == void.class && !StringUtils.hasLength(blockMethod)) {\n\t\t\treturn;\n\t\t}\n\t\tif (blockClass != void.class && !StringUtils.hasLength(blockMethod)) {\n\t\t\tlog.error(\n\t\t\t\t\t\"{} class attribute exists but {} method attribute is not exists in bean[{}]\",\n\t\t\t\t\ttype, type, beanName);\n\t\t\tthrow new IllegalArgumentException(type + \" class attribute exists but \"\n\t\t\t\t\t+ type + \" method attribute is not exists in bean[\" + beanName + \"]\");\n\t\t}\n\t\telse if (blockClass == void.class && StringUtils.hasLength(blockMethod)) {\n\t\t\tlog.error(\n\t\t\t\t\t\"{} method attribute exists but {} class attribute is not exists in bean[{}]\",\n\t\t\t\t\ttype, type, beanName);\n\t\t\tthrow new IllegalArgumentException(type + \" method attribute exists but \"\n\t\t\t\t\t+ type + \" class attribute is not exists in bean[\" + beanName + \"]\");\n\t\t}\n\t\tClass[] args;\n\t\tif (type.equals(SentinelConstants.URLCLEANER_TYPE)) {\n\t\t\targs = new Class[] {String.class};\n\t\t}\n\t\telse {\n\t\t\targs = new Class[] {HttpRequest.class, byte[].class,\n\t\t\t\t\tClientHttpRequestExecution.class, BlockException.class};\n\t\t}\n\t\tString argsStr = Arrays.toString(","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/alibaba/spring-cloud-alibaba/blob/115d5901102009492e05d5ec18c3f79cad4077d0/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelBeanPostProcessor.java#L99-L135","documentation":"SentinelBeanPostProcessor validates RestTemplate-level Sentinel configuration for block/fallback/urlCleaner handlers. Each handler is specified by a pair of attributes: a class (blockClass/fallbackClass/urlCleanerClass) and a method name. This IllegalArgumentException fires when a class attribute is present but the matching method-name attribute is empty/missing. It is a configuration-time error that aborts bean post-processing at startup.","triggerScenarios":"Annotating or configuring a RestTemplate Sentinel handler with only the class, e.g. spring.cloud.sentinel.resttemplate.block-class=com.example.MyBlock without a block-method property, or @SentinelRestTemplate(blockClass = MyBlock.class) with no blockMethod.","commonSituations":"Copying a working handler but deleting the method line. Renaming the method attribute and forgetting to keep it. Assuming the class alone exposes a default handler method.","solutions":["Add the matching method attribute, e.g. spring.cloud.sentinel.resttemplate.block-method=handleBlock, or blockMethod = \"handleBlock\".","If you intended class-only config, remove the class attribute so both are treated as unset (the method returns early when both are empty).","Ensure the method name exists on the referenced class and is a public static method with the documented signature."],"exampleFix":"// before\n@SentinelRestTemplate(blockClass = MyBlock.class)\n// after\n@SentinelRestTemplate(blockClass = MyBlock.class, blockMethod = \"handleBlock\")","handlingStrategy":"validation","validationCode":"void validateHandler(Class<?> clazz, String method) {\n  boolean hasClass = clazz != null && clazz != void.class;\n  boolean hasMethod = method != null && !method.isBlank();\n  if (hasClass != hasMethod) throw new IllegalStateException(\"class and method attributes must both be set or both be empty\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair a -class property with a -method property.","Add a config sanity test at startup.","Document the pairing in your team's sentinel config template."],"tags":["sentinel","resttemplate","config-validation","startup"],"backgroundTag":null,"analyzedSha":"115d5901102009492e05d5ec18c3f79cad4077d0","analyzedAt":"2026-08-14T04:47:13.900Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}