{"record":{"id":"60211935ce758308","repo":"apache/shenyu","slug":"rule-exist-under-those-namespace","errorCode":null,"errorMessage":"rule exist under those namespace!","messagePattern":"rule exist under those namespace!","errorType":"exception","errorClass":"ShenyuAdminException","httpStatus":null,"severity":"error","filePath":"shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java","lineNumber":145,"sourceCode":"        namespaceQuery.setNamespaceIds(namespaceIds);\n        return PageResultUtils.result(namespaceQuery.getPageParameter(), () -> namespaceMapper.countByQuery(namespaceQuery), () -> namespaceMapper.selectByQuery(namespaceQuery)\n                .stream()\n                .map(NamespaceTransfer.INSTANCE::mapToVo)\n                .collect(Collectors.toList()));\n    }\n\n    @Override\n    public String delete(final List<String> ids) {\n        if (ids.contains(Constants.DEFAULT_NAMESPACE_PRIMARY_KEY)) {\n            throw new ShenyuAdminException(AdminConstants.SYS_DEFAULT_NAMESPACE_ID_DELETE);\n        }\n        List<String> namespaceIdList = namespaceMapper.selectByIds(ids).stream().map(NamespaceDO::getNamespaceId).collect(Collectors.toList());\n        if (CollectionUtils.isEmpty(namespaceIdList)) {\n            throw new ShenyuAdminException(AdminConstants.SYS_NAMESPACE_ID_NOT_EXIST);\n        }\n        List<RuleDO> ruleDOList = ruleMapper.selectAllByNamespaceIds(namespaceIdList);\n        if (CollectionUtils.isNotEmpty(ruleDOList)) {\n            throw new ShenyuAdminException(\"rule exist under those namespace!\");\n        }\n        List<SelectorDO> selectorDOS = selectorMapper.selectAllByNamespaceIds(namespaceIdList);\n        if (CollectionUtils.isNotEmpty(selectorDOS)) {\n            throw new ShenyuAdminException(\"selector exist under those namespace!\");\n        }\n        List<NamespacePluginVO> namespacePluginVOS = namespacePluginRelMapper.selectAllByNamespaceIds(namespaceIdList);\n        if (CollectionUtils.isNotEmpty(namespacePluginVOS)) {\n            throw new ShenyuAdminException(\"Plugins exist under those namespace!\");\n        }\n        List<MetaDataDO> metaDataDOList = metaDataMapper.findAllByNamespaceIds(namespaceIdList);\n        if (CollectionUtils.isNotEmpty(metaDataDOList)) {\n            throw new ShenyuAdminException(\"metaData exist under those namespace!\");\n        }\n        List<AppAuthDO> appPathDOList = appAuthMapper.findByNamespaceIds(namespaceIdList);\n        if (CollectionUtils.isNotEmpty(appPathDOList)) {\n            throw new ShenyuAdminException(\"appPath exist under those namespace!\");\n        }\n        namespaceMapper.deleteByIds(ids);","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java#L127-L163","documentation":"Thrown by NamespaceServiceImpl.delete when RuleDO rows still reference the namespaces being deleted. Namespaces must be empty of configuration before deletion; the guard checks ruleMapper.selectAllByNamespaceIds and aborts so gateway rule data is never orphaned.","triggerScenarios":"Calling DELETE /namespace while any rule (created via dashboard selectors/rules UI or client metadata registration) exists under one of the target namespaces.","commonSituations":"Decommissioning a namespace that still has active API rules; forgetting that client-side (Spring Cloud/Motan/etc.) registration auto-created rules; deleting parent config without cleaning rules first.","solutions":["Delete or migrate all rules under the namespaces via the rule API/dashboard, then retry","Check rule list filtered by namespaceIds to see which rules block deletion","Unregister the backend clients publishing rules into that namespace, then clean up","If rules are truly orphaned, remove them directly in the DB/admin before deleting"],"exampleFix":"// before\nnamespaceService.delete(ids);\n// after\nList<RuleDTO> rules = ruleService.selectAllByNamespaceIds(namespaceIds);\nif (rules.isEmpty()) {\n    namespaceService.delete(ids);\n} else {\n    ruleService.delete(rules.stream().map(RuleDTO::getId).collect(Collectors.toList()));\n    namespaceService.delete(ids);\n}","handlingStrategy":"validation","validationCode":"List<RuleDO> rules = ruleMapper.selectAllByNamespaceIds(namespaceIds);\nif (!rules.isEmpty()) {\n    throw new IllegalStateException(\"delete rules first: \" + rules.size() + \" remain\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    namespaceService.delete(ids);\n} catch (ShenyuAdminException e) {\n    if (e.getMessage().startsWith(\"rule exist under those namespace\")) {\n        LOG.warn(\"namespace deletion blocked: rules still exist\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Before deleting a namespace, list and purge its rules, then selectors and plugin relations","Disable/unregister backend clients that auto-publish rules into the namespace","Follow the cleanup order: rules -> selectors -> namespace plugins -> namespace"],"tags":["shenyu","admin","namespace","referential-integrity"],"backgroundTag":"invalid-state-transition","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"}