apache/shenyu · error · ShenyuException

the method cannot be called, please check the annotation…

Error message

the method cannot be called, please check the annotation and configuration, method %s

What it means

ShenyuClientInvocationHandler.invoke() dispatches proxied interface methods through a prebuilt methodHandlerMap. Only methods that carry a recognized Shenyu HTTP annotation get a handler; anything else (Object methods or un-annotated methods) has no mapping and throws ShenyuException. It signals an API-definition problem: the proxy was asked to execute a method it was never configured to call.

Solutions

  1. Annotate the called method with a supported HTTP mapping annotation matching its role (@Get, @Post, ...).
  2. Verify the annotation import is the Shenyu SDK one, not a look-alike from another library.
  3. Ensure the annotation is on the interface method the proxy is built from, not only on an implementation.
  4. For non-HTTP helper methods, make them default methods with local logic, or move them out of the client interface.

Example fix

// before
public interface OrderApi {
    OrderDTO getById(Long id);
}
// after
public interface OrderApi {
    @Get("/order/detail")
    OrderDTO getById(@RequestParam("id") Long id);
}
Defensive patterns

Strategy: type-guard

Type guard

static boolean isMappedClientMethod(Method m) {
    return m.getDeclaringClass() != Object.class
        && (m.isAnnotationPresent(Get.class) || m.isAnnotationPresent(Post.class)
            || m.isAnnotationPresent(Put.class) || m.isAnnotationPresent(Delete.class));
}

Prevention

When it happens

Trigger: Calling a method on a @ShenyuClient interface that lacks an HTTP mapping annotation (@Get/@Post/...), or invoking toString/hashCode/equals on the proxy expecting them to be routed.

Common situations: Adding a new interface method and forgetting the mapping annotation; annotation on the implementation class instead of the interface; wrong import of the mapping annotation so the scanner ignores it; calling default methods through the proxy.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/44aa5c9e3cd51b85. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientInvocationHandler.java:81

    private final FallbackFactory<?> fallbackFactory;

    public ShenyuClientInvocationHandler(final Class<?> apiClass, final ApplicationContext applicationContext,
                                         final ShenyuClientFactoryBean shenyuClientFactoryBean) {
        this.shenyuClientFactoryBean = shenyuClientFactoryBean;
        this.applicationContext = applicationContext;
        this.contract = applicationContext.getBean(Contract.class);
        ShenyuClient shenyuClient = apiClass.getAnnotation(ShenyuClient.class);
        fallbackFactory = getFallbackFactory(shenyuClientFactoryBean.getFallback(),
                shenyuClientFactoryBean.getFallbackFactory());
        buildMethodHandlerMap(apiClass, shenyuClient);
    }

    @Override
    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {

        ShenyuClientMethodHandler handler = methodHandlerMap.get(method);
        if (ObjectUtils.isEmpty(handler)) {
            throw new ShenyuException(String.format("the method cannot be called, please check the annotation and configuration, method %s", method.getName()));
        }
        Object result;
        try {
            result = handler.invoke(args);
        } catch (Throwable throwable) {
            LOG.error("ShenYu Client invoke error  ", throwable);
            if (Objects.isNull(fallbackFactory)) {
                throw new NoFallbackAvailableException("No fallback available.", throwable);
            }
            Object fallback = fallbackFactory.create(throwable);
            result = method.invoke(fallback, args);
        }
        return result;
    }

    private void buildMethodHandlerMap(final Class<?> apiClass, final ShenyuClient shenyuClient) {
        // parseAndValidate RequestTemplate
        final List<RequestTemplate> requestTemplates = contract.parseAndValidateRequestTemplate(apiClass, shenyuClientFactoryBean);

View on GitHub (pinned to 567142e072)