apache/shenyu · error · ShenyuClientIllegalArgumentException

client register param must config the appName or contextPath

Error message

client register param must config the appName or contextPath

What it means

The same constructor validates that at least one of appName or contextPath is set in the client props; if both are blank it throws ShenyuClientIllegalArgumentException with this fixed message. ShenYu needs one of them to build the client registration (RPC type/context path) sent to the admin.

Solutions

  1. Set contextPath (and typically appName) under shenyu.<clientName>.props in application.yml
  2. Check for key typos — the properties must be named appName and contextPath exactly
  3. Verify the props block is under the correct client name key matching the starter in use
  4. Restart the client app so the refreshed context picks up the new properties

Example fix

// before
shenyu:
  client:
    http:
      props: {}
// after
shenyu:
  client:
    http:
      props:
        contextPath: /myapi
        appName: myapi
        port: 8181
Defensive patterns

Strategy: validation

Validate before calling

// pre-check props before startup
Properties props = /* shenyu.client.<name>.props */;
String appName = props.getProperty("appName");
String contextPath = props.getProperty("contextPath");
if ((appName == null || appName.isBlank()) && (contextPath == null || contextPath.isBlank())) {
    throw new IllegalStateException("set appName or contextPath in shenyu client props");
}

Try / catch

try {
    context.refresh();
} catch (ShenyuClientIllegalArgumentException e) {
    log.error("Registration config invalid: {}", e.getMessage());
    // add appName/contextPath and restart
}

Prevention

When it happens

Trigger: Constructing the listener when props from shenyu.<clientName>.props lack both appName and contextPath — e.g. empty props map or only unrelated keys present.

Common situations: New service onboarded with only register address configured and no props; contextPath typo'd (e.g. context-path); props nested under the wrong client key so they're never read; config trimmed down during cleanup.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/client/AbstractContextRefreshedEventListener.java:134

    public AbstractContextRefreshedEventListener(final ShenyuClientConfig clientConfig,
                                                 final ShenyuClientRegisterRepository shenyuClientRegisterRepository) {
        ClientPropertiesConfig config = clientConfig.getClient().get(getClientName());
        if (Objects.isNull(config)) {
            throw new ShenyuClientIllegalArgumentException("clientConfig must config " + getClientName() + " properties");
        }
        Properties props = config.getProps();
        String namespace = clientConfig.getNamespace();
        if (StringUtils.isBlank(namespace)) {
            LOG.warn("current shenyu.namespace is null, use default namespace: {}", Constants.SYS_DEFAULT_NAMESPACE_ID);
            namespace = Constants.SYS_DEFAULT_NAMESPACE_ID;
        }
        this.namespace = Lists.newArrayList(StringUtils.split(namespace, Constants.SEPARATOR_CHARS));
        this.appName = props.getProperty(ShenyuClientConstants.APP_NAME);
        this.contextPath = Optional.ofNullable(props.getProperty(ShenyuClientConstants.CONTEXT_PATH)).map(UriUtils::repairData).orElse("");
        if (StringUtils.isBlank(appName) && StringUtils.isBlank(contextPath)) {
            String errorMsg = "client register param must config the appName or contextPath";
            LOG.error(errorMsg);
            throw new ShenyuClientIllegalArgumentException(errorMsg);
        }
        this.ipAndPort = props.getProperty(ShenyuClientConstants.IP_PORT);
        this.host = props.getProperty(ShenyuClientConstants.HOST);
        this.port = props.getProperty(ShenyuClientConstants.PORT);
        publisher.start(shenyuClientRegisterRepository);
    }

    @Override
    public void onApplicationEvent(@NonNull final ContextRefreshedEvent event) {
        context = event.getApplicationContext();
        Map<String, T> beans = getBeans(context);
        if (MapUtils.isEmpty(beans)) {
            return;
        }
        if (!markRegistered()) {
            return;
        }
        String discoveryMode = context.getEnvironment()

View on GitHub (pinned to 567142e072)