alibaba/spring-ai-alibaba · error · BizException
INVALID_PARAMS
INVALID_PARAMS
Error message
provider already exists
What it means
ProviderManager.addProvider throws BizException(INVALID_PARAMS, 'provider already exists') when a provider with the same name already exists in the target workspace — getProviderEntity(provider, workspaceId) returns a non-null row. It enforces per-workspace uniqueness of provider names and is thrown before any insert happens.
Source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/manager/ProviderManager.java:75
* Add a new provider
* @param providerConfigInfo Provider configuration information
* @return true if successful
*/
public boolean addProvider(ProviderConfigInfo providerConfigInfo) {
RequestContext context = RequestContextHolder.getRequestContext();
String workspaceId = context.getWorkspaceId();
try {
// 检查提供商是否存在
QueryWrapper<ProviderEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("provider", providerConfigInfo.getProvider());
if (StringUtils.isNotBlank(context.getWorkspaceId())) {
queryWrapper.eq("workspace_id", context.getWorkspaceId());
}
String provider = providerConfigInfo.getProvider();
ProviderEntity existingProvider = getProviderEntity(provider, workspaceId);
if (existingProvider != null) {
log.error("provider [{}] already exist", providerConfigInfo.getProvider());
throw new BizException(ErrorCode.INVALID_PARAMS.toError("input_params", "provider already exists"));
}
ProviderEntity providerEntity = new ProviderEntity();
providerEntity.setWorkspaceId(context.getWorkspaceId());
providerEntity.setGmtCreate(new Date());
providerEntity.setGmtModified(new Date());
providerEntity.setIcon(providerConfigInfo.getIcon());
providerEntity.setName(providerConfigInfo.getName());
providerEntity.setProvider(providerConfigInfo.getProvider());
providerEntity.setDescription(providerConfigInfo.getDescription());
providerEntity.setSource(StringUtils.isNotBlank(providerConfigInfo.getSource())
? providerConfigInfo.getSource() : DataSourceEnum.custom.name());
providerEntity.setEnable(providerConfigInfo.getEnable() != null ? providerConfigInfo.getEnable() : true);
providerEntity.setCredential(providerConfigInfo.getCredential() == null ? "{}"
: JsonUtils.toJson(providerConfigInfo.getCredential()));
providerEntity.setSupportedModelTypes(
providerConfigInfo.getSupportedModelTypes().stream().collect(Collectors.joining(",")));
providerEntity.setCreator(context.getAccountId());View on GitHub (pinned to f82da0b50f)
Solutions
- Check for the provider's existence first (query providers in the workspace) and update instead of insert if present
- Use a different provider name if a distinct provider is intended
- Make creation idempotent: catch this BizException and treat it as success when re-registering the same config
- Deduplicate seed/init scripts so they run only once
Example fix
// before
providerManager.addProvider(config);
// after
try {
providerManager.addProvider(config);
} catch (BizException e) {
if (e.getMessage() != null && e.getMessage().contains("provider already exists")) {
log.info("Provider {} already registered, skipping", config.getProvider());
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
boolean providerExists = providerManager.getProviders(workspaceId).stream()
.anyMatch(p -> p.getProvider().equals(config.getProvider()));
if (providerExists) { /* update instead of create */ } Type guard
boolean providerExistsInWorkspace(String provider, String workspaceId) {
return provider != null
&& providerManager.getProviders(workspaceId).stream()
.anyMatch(p -> p.getProvider().equals(provider));
} Try / catch
try {
providerManager.addProvider(config);
} catch (BizException e) {
if (e.getMessage() != null && e.getMessage().contains("provider already exists")) {
providerManager.updateProvider(config); // idempotent upsert
} else {
throw e;
}
} Prevention
- Implement upsert semantics: check-then-update instead of blind insert
- Guard seed/init scripts against double execution
- Disable double-submit on creation UIs
- Document that provider names are unique per workspace
When it happens
Trigger: Calling addProvider with a providerConfigInfo whose provider name matches an existing row in the same workspace (case-exact match on the provider column).
Common situations: Double-submitting a creation form; retrying a request that actually succeeded the first time; seeding scripts run twice; trying to register a built-in provider name that already exists in the workspace.
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 alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/ffd8467e69c57aad.
Report an issue: GitHub.