{"record":{"id":"f2b3e5c111a49ef3","repo":"apache/shenyu","slug":"group-param-invalid-s","errorCode":null,"errorMessage":"group param invalid:%s","messagePattern":"group param invalid:(.+?)","errorType":"validation","errorClass":"ShenyuException","httpStatus":null,"severity":"error","filePath":"shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/http/HttpLongPollingDataChangedListener.java","lineNumber":214,"sourceCode":"\n    @Override\n    protected void afterProxySelectorChanged(final List<ProxySelectorData> changed, final DataEventTypeEnum eventType, final String namespaceId) {\n        scheduler.execute(new DataChangeTask(ConfigGroupEnum.PROXY_SELECTOR, namespaceId));\n    }\n\n    @Override\n    protected void afterDiscoveryUpstreamDataChanged(final List<DiscoverySyncData> changed, final DataEventTypeEnum eventType, final String namespaceId) {\n        scheduler.execute(new DataChangeTask(ConfigGroupEnum.DISCOVER_UPSTREAM, namespaceId));\n    }\n\n    private List<ConfigGroupEnum> compareChangedGroup(final HttpServletRequest request) {\n        List<ConfigGroupEnum> changedGroup = new ArrayList<>(ConfigGroupEnum.values().length);\n        String namespaceId = getNamespaceId(request);\n        for (ConfigGroupEnum group : ConfigGroupEnum.values()) {\n            // md5,lastModifyTime\n            String[] params = StringUtils.split(request.getParameter(group.name()), ',');\n            if (Objects.isNull(params) || params.length != 2) {\n                throw new ShenyuException(\"group param invalid:\" + request.getParameter(group.name()));\n            }\n            String clientMd5 = params[0];\n            long clientModifyTime = NumberUtils.toLong(params[1]);\n\n            ConfigDataCache serverCache = CACHE.get(buildCacheKey(namespaceId, group.name()));\n            // do check.\n            if (this.checkCacheDelayAndUpdate(serverCache, clientMd5, clientModifyTime)) {\n                changedGroup.add(group);\n            }\n        }\n        return changedGroup;\n    }\n\n    public static String buildCacheKey(final String namespaceId, final String group) {\n        return namespaceId + \"_\" + group;\n    }\n\n    /**","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/http/HttpLongPollingDataChangedListener.java#L196-L232","documentation":"In the HTTP long-polling data sync listener, each gateway client sends a request parameter per config group (PLUGIN, SELECTOR, RULE, ...) in the format \"<md5>,<lastModifyTime>\". compareChangedGroup splits that parameter on ','; if the parameter is missing or doesn't contain exactly two comma-separated parts, it throws ShenyuException. This guards the long-polling contract between gateway and admin.","triggerScenarios":"A gateway (or any HTTP client) calls the admin /configs/listener endpoint without a `group` query parameter, or with a value that has no comma or more than one comma, e.g. `?PLUGIN=abc123` instead of `?PLUGIN=abc123,1690000000000`.","commonSituations":"Hand-rolled scripts or curl calls hitting the listener endpoint; a gateway version whose long-polling wire format differs from the admin's (version skew after upgrade); proxies/gateways stripping or truncating query parameters; sending md5 values that contain characters a URL-encoding layer mangled.","solutions":["Use the official shenyu-sync-data-http-client instead of custom HTTP calls, so parameters are built as \"md5,modifyTime\" per group.","Check the request URL sent by the gateway; ensure every ConfigGroupEnum name has a `<md5>,<lastModifyTime>` value, URL-encoded.","Align gateway and admin versions — the long-polling parameter format must match on both sides.","If behind a proxy, confirm query strings are not being rewritten or truncated."],"exampleFix":"// before\ncurl 'http://admin:9095/configs/listener?PLUGIN=abc'\n// after\ncurl 'http://admin:9095/configs/listener?PLUGIN=abc123def,1690000000000&SELECTOR=...,&RULE=...'","handlingStrategy":"validation","validationCode":"String param = group + \"=\" + md5 + \",\" + lastModifyTime;\nif (md5 == null || !md5.matches(\"[0-9a-f]{32}\")) throw new IllegalStateException(\"bad md5 for \" + group);","typeGuard":null,"tryCatchPattern":"try {\n    listener.compareChangedGroup(request);\n} catch (ShenyuException e) {\n    LOG.warn(\"malformed long-polling param: {}\", e.getMessage());\n    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);\n}","preventionTips":["Use the official shenyu http sync client rather than hand-built requests","Always URL-encode the md5,modifyTime pair","Keep gateway and admin versions aligned"],"tags":["long-polling","data-sync","http","parameter-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}