apache/shenyu · error · ShenyuAdminException

rule exist under those namespace!

Error message

rule exist under those namespace!

What it means

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.

Solutions

  1. Delete or migrate all rules under the namespaces via the rule API/dashboard, then retry
  2. Check rule list filtered by namespaceIds to see which rules block deletion
  3. Unregister the backend clients publishing rules into that namespace, then clean up
  4. If rules are truly orphaned, remove them directly in the DB/admin before deleting

Example fix

// before
namespaceService.delete(ids);
// after
List<RuleDTO> rules = ruleService.selectAllByNamespaceIds(namespaceIds);
if (rules.isEmpty()) {
    namespaceService.delete(ids);
} else {
    ruleService.delete(rules.stream().map(RuleDTO::getId).collect(Collectors.toList()));
    namespaceService.delete(ids);
}
Defensive patterns

Strategy: validation

Validate before calling

List<RuleDO> rules = ruleMapper.selectAllByNamespaceIds(namespaceIds);
if (!rules.isEmpty()) {
    throw new IllegalStateException("delete rules first: " + rules.size() + " remain");
}

Try / catch

try {
    namespaceService.delete(ids);
} catch (ShenyuAdminException e) {
    if (e.getMessage().startsWith("rule exist under those namespace")) {
        LOG.warn("namespace deletion blocked: rules still exist");
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling DELETE /namespace while any rule (created via dashboard selectors/rules UI or client metadata registration) exists under one of the target namespaces.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java:145

        namespaceQuery.setNamespaceIds(namespaceIds);
        return PageResultUtils.result(namespaceQuery.getPageParameter(), () -> namespaceMapper.countByQuery(namespaceQuery), () -> namespaceMapper.selectByQuery(namespaceQuery)
                .stream()
                .map(NamespaceTransfer.INSTANCE::mapToVo)
                .collect(Collectors.toList()));
    }

    @Override
    public String delete(final List<String> ids) {
        if (ids.contains(Constants.DEFAULT_NAMESPACE_PRIMARY_KEY)) {
            throw new ShenyuAdminException(AdminConstants.SYS_DEFAULT_NAMESPACE_ID_DELETE);
        }
        List<String> namespaceIdList = namespaceMapper.selectByIds(ids).stream().map(NamespaceDO::getNamespaceId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(namespaceIdList)) {
            throw new ShenyuAdminException(AdminConstants.SYS_NAMESPACE_ID_NOT_EXIST);
        }
        List<RuleDO> ruleDOList = ruleMapper.selectAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(ruleDOList)) {
            throw new ShenyuAdminException("rule exist under those namespace!");
        }
        List<SelectorDO> selectorDOS = selectorMapper.selectAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(selectorDOS)) {
            throw new ShenyuAdminException("selector exist under those namespace!");
        }
        List<NamespacePluginVO> namespacePluginVOS = namespacePluginRelMapper.selectAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(namespacePluginVOS)) {
            throw new ShenyuAdminException("Plugins exist under those namespace!");
        }
        List<MetaDataDO> metaDataDOList = metaDataMapper.findAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(metaDataDOList)) {
            throw new ShenyuAdminException("metaData exist under those namespace!");
        }
        List<AppAuthDO> appPathDOList = appAuthMapper.findByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(appPathDOList)) {
            throw new ShenyuAdminException("appPath exist under those namespace!");
        }
        namespaceMapper.deleteByIds(ids);

View on GitHub (pinned to 567142e072)