apache/shenyu · error · ShenyuAdminException

The plugin of namespace is exist!

Error message

The plugin of namespace is exist!

What it means

Thrown by NamespacePluginServiceImpl.create when a plugin-to-namespace relation already exists for the given pluginId and namespaceId. Each plugin can be enabled in a namespace only once, so a duplicate insert is rejected with AdminConstants.NAMESPACE_PLUGIN_EXIST.

Solutions

  1. Check existing bindings first via the namespace-plugin list API for that namespaceId/pluginId
  2. Make the enable operation idempotent: skip creation when the relation already exists
  3. Treat the existing relation as success and return it instead of inserting
  4. Serialize/rate-limit duplicate requests from UI clients

Example fix

// before
namespacePluginService.create(namespaceId, pluginId);
// after
if (namespacePluginService.findByPluginIdAndNamespaceId(pluginId, namespaceId) == null) {
    namespacePluginService.create(namespaceId, pluginId);
}
Defensive patterns

Strategy: validation

Validate before calling

NamespacePluginVO existing = namespacePluginRelMapper.selectByPluginIdAndNamespaceId(pluginId, namespaceId);
if (existing != null) {
    return existing;
}

Try / catch

try {
    namespacePluginService.create(namespaceId, pluginId);
} catch (ShenyuAdminException e) {
    if (AdminConstants.NAMESPACE_PLUGIN_EXIST.equals(e.getMessage())) {
        LOG.info("plugin {} already bound to namespace {}", pluginId, namespaceId);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling POST /namespace-plugin to enable a plugin in a namespace where it is already enabled; double-clicking/retrying the enable action in the dashboard; concurrent requests racing past the selectByPluginIdAndNamespaceId existence check.

Common situations: Re-running an initialization script that binds default plugins to a namespace; UI state out of sync after another admin enabled the plugin; API scripts without idempotency checks.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespacePluginServiceImpl.java:97

        this.selectorMapper = selectorMapper;
        this.pluginHandleMapper = pluginHandleMapper;
    }
    
    @Override
    public NamespacePluginVO findById(final String id) {
        return namespacePluginRelMapper.selectById(id);
    }
    
    @Override
    public NamespacePluginVO findByNamespaceIdAndPluginId(final String namespaceId, final String pluginId) {
        return namespacePluginRelMapper.selectByPluginIdAndNamespaceId(pluginId, namespaceId);
    }
    
    @Override
    public NamespacePluginVO create(final String namespaceId, final String pluginId) {
        NamespacePluginVO existNamespacePluginVO = namespacePluginRelMapper.selectByPluginIdAndNamespaceId(pluginId, namespaceId);
        if (Objects.nonNull(existNamespacePluginVO)) {
            throw new ShenyuAdminException(AdminConstants.NAMESPACE_PLUGIN_EXIST);
        }
        PluginDO pluginDO = pluginMapper.selectById(pluginId);
        NamespacePluginRelDO namespacePluginRelDO = NamespacePluginRelDO.buildNamespacePluginRelDO(pluginDO, namespaceId);
        namespacePluginRelMapper.insertSelective(namespacePluginRelDO);
        return namespacePluginRelMapper.selectByPluginIdAndNamespaceId(pluginId, namespaceId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String update(final NamespacePluginDTO namespacePluginDTO) {
        final NamespacePluginVO before = namespacePluginRelMapper.selectById(namespacePluginDTO.getId());
        NamespacePluginRelDO namespacePluginRelDO = NamespacePluginRelDO.buildNamespacePluginRelDO(namespacePluginDTO);
        if (namespacePluginRelMapper.updateSelective(namespacePluginRelDO) > 0) {
            final NamespacePluginVO now = namespacePluginRelMapper.selectById(namespacePluginDTO.getId());
            // publish update event.
            namespacePluginEventPublisher.onUpdated(now, before);
        }
        return ShenyuResultMessage.UPDATE_SUCCESS;

View on GitHub (pinned to 567142e072)