apache/shenyu · error · UnsupportedOperationException
If the preMatch method was implemented ,the preParse method…
Error message
If the preMatch method was implemented ,the preParse method should be implemented.
What it means
AbstractApiRegistrar lets subclasses override preMatch to filter APIs before parsing; the default preParse hook throws UnsupportedOperationException as a contract guard: if a subclass (or its caller path) relies on pre-parsing but only preMatch was overridden, the framework deliberately fails fast instead of silently mis-registering APIs.
Solutions
- Override preParse(ApiBean) in your registrar subclass and return the registrable DTO built from the apiBean.
- Alternatively remove your preMatch override if you did not intend custom filtering, letting the default pipeline handle parse+match.
- Check the sibling registrar implementations (e.g. SpringMvcApiRegistrar) for the expected preParse pattern and mirror it.
Example fix
// before
@Override
protected boolean preMatch(final ApiBean apiBean) {
return super.preMatch(apiBean);
}
// after
@Override
protected boolean preMatch(final ApiBean apiBean) {
return super.preMatch(apiBean);
}
@Override
protected D preParse(final ApiBean apiBean) {
return buildApiDefinition(apiBean);
} Defensive patterns
Strategy: type-guard
Validate before calling
// before registering, assert the contract
if (registrarOverridesPreMatch(registrar) && !registrarOverridesPreParse(registrar)) {
throw new IllegalStateException("registrar must implement preParse alongside preMatch");
} Type guard
// reflection guard
boolean overridesPreParse(AbstractApiRegistrar<?> r) {
try {
return !AbstractApiRegistrar.class
.getDeclaredMethod("preParse", ApiBean.class)
.equals(r.getClass().getDeclaredMethod("preParse", ApiBean.class));
} catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
registrar.register(apiBean);
} catch (UnsupportedOperationException e) {
LOGGER.error("registrar parse contract violated: {}", e.getMessage());
throw e;
} Prevention
- When overriding preMatch, always override preParse in the same subclass.
- Mirror an existing registrar implementation when writing new ones.
- Add a unit test that exercises register() on your registrar.
When it happens
Trigger: A custom ApiRegistrar subclass overrides preMatch (or invokes the preParse contract) but does not override preParse, and the generic register() flow reaches preParse(apiBean) on an apiBean whose definitions cannot be parsed by the base implementation.
Common situations: Writing a custom client registrar (e.g. for a new framework) and implementing only half of the parse/match contract; upgrading Shenyu where a base class previously handled parsing internally.
Understand the failure class
Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.
Related errors
- namespaceId is not exist
- The configuration shenyu.discovery.type in xml/yml cannot…
- can not find port automatically !
- tars client must config the contextPath, ipAndPort
- Class missing annotation ShenyuServerEndpoint! class name:
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/c91cb5b094664c07.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/registrar/AbstractApiRegistrar.java:51
/**
* Determines whether the apiBean can be registered in advance.
*
* @param apiBean apiBean to be registered
* @return true or false
*/
protected Boolean preMatch(final ApiBean apiBean) {
return false;
}
/**
* Parses the apiBean as a registrable object.
*
* @param apiBean apiBean to be parsed
* @return registrable object
*/
protected D preParse(final ApiBean apiBean) {
throw new UnsupportedOperationException("If the preMatch method was implemented ,the preParse method should be implemented.");
}
/**
* Determines whether apiDefinitions of apiBean can be filtered.
*
* @param apiBean apiBean to be registered
* @return true or false
*/
protected abstract Boolean match(ApiBean apiBean);
/**
* Determines whether the apiDefinition can be registered.
*
* @param apiDefinition apiDefinition to be registered
* @return true or false
*/
protected abstract Boolean match(ApiBean.ApiDefinition apiDefinition);
View on GitHub (pinned to 567142e072)