{"record":{"id":"50a032e8e6054bdb","repo":"alibaba/nacos","slug":"400-50a032","errorCode":"400","errorMessage":"[Batch deRegistration] need deRegister instance is empty, instances: %s,","messagePattern":"\\[Batch deRegistration\\] need deRegister instance is empty, instances: (.+?),","errorType":"exception","errorClass":"NacosException","httpStatus":400,"severity":"error","filePath":"client/src/main/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxy.java","lineNumber":202,"sourceCode":"        synchronized (redoService.getRegisteredInstances()) {\n            List<Instance> retainInstance = getRetainInstance(serviceName, groupName, instances);\n            batchRegisterService(serviceName, groupName, retainInstance);\n        }\n    }\n    \n    /**\n     * Get instance list that need to be Retained.\n     *\n     * @param serviceName         service name\n     * @param groupName           group name\n     * @param deRegisterInstances deregister instance list\n     * @return instance list that need to be retained.\n     */\n    private List<Instance> getRetainInstance(String serviceName, String groupName,\n        List<Instance> deRegisterInstances)\n        throws NacosException {\n        if (CollectionUtils.isEmpty(deRegisterInstances)) {\n            throw new NacosException(NacosException.INVALID_PARAM,\n                String.format(\n                    \"[Batch deRegistration] need deRegister instance is empty, instances: %s,\",\n                    deRegisterInstances));\n        }\n        String combinedServiceName = NamingUtils.getGroupedName(serviceName, groupName);\n        InstanceRedoData instanceRedoData =\n            redoService.getRegisteredInstancesByKey(combinedServiceName);\n        if (!(instanceRedoData instanceof BatchInstanceRedoData)) {\n            throw new NacosException(NacosException.INVALID_PARAM, String.format(\n                \"[Batch deRegistration] batch deRegister is not BatchInstanceRedoData type , instances: %s,\",\n                deRegisterInstances));\n        }\n        \n        BatchInstanceRedoData batchInstanceRedoData = (BatchInstanceRedoData) instanceRedoData;\n        List<Instance> allRedoInstances = batchInstanceRedoData.getInstances();\n        if (CollectionUtils.isEmpty(allRedoInstances)) {\n            throw new NacosException(NacosException.INVALID_PARAM, String.format(\n                \"[Batch deRegistration] not found all registerInstance , serviceName：%s , groupName: %s\",","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/client/src/main/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxy.java#L184-L220","documentation":"Thrown by NamingGrpcClientProxy.batchDeregisterService when the deregister instance list passed to getRetainInstance is null or empty (NacosException.INVALID_PARAM = 400). The client refuses to process a batch deregistration with no target instances because there is nothing to subtract from the redo set.","triggerScenarios":"Calling namingService.batchDeregisterService(serviceName, groupName, Collections.emptyList()) or passing a null list. Can also occur if upstream code filters the list down to zero entries before forwarding it.","commonSituations":"Application shutdown logic that deregisters a computed set of instances which happens to be empty; a conditional that removes all instances from the list before calling batchDeregisterService; copy-paste of a register call where the list was never populated.","solutions":["Guard the call: only invoke batchDeregisterService when the instances list is non-empty.","If the intent is a no-op when the list is empty, short-circuit with an if-check before calling the API.","Review upstream filtering logic that produces the deregister list to ensure it retains the intended instances."],"exampleFix":"// before\nnamingService.batchDeregisterService(serviceName, groupName, toRemove);\n\n// after\nif (toRemove != null && !toRemove.isEmpty()) {\n    namingService.batchDeregisterService(serviceName, groupName, toRemove);\n}","handlingStrategy":"validation","validationCode":"if (instances == null || instances.isEmpty()) {\n    // skip batch deregister — nothing to remove\n    return;\n}\nnamingService.batchDeregisterService(serviceName, groupName, instances);","typeGuard":null,"tryCatchPattern":"try {\n    namingService.batchDeregisterService(serviceName, groupName, instances);\n} catch (NacosException e) {\n    if (e.getErrCode() == NacosException.INVALID_PARAM\n        && e.getErrMsg().contains(\"need deRegister instance is empty\")) {\n        // benign — list was empty, nothing to deregister\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always check that the deregister list is non-empty before calling batchDeregisterService.","Treat an empty deregister list as a no-op rather than forwarding it to the API."],"tags":["naming","batch-deregister","validation","client"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}