iflytek/astron-agent · warning · BusinessException
BOT_API_CREATE_LIMIT_ERROR
BOT_API_CREATE_LIMIT_ERROR
Error message
BOT_API_CREATE_LIMIT_ERROR
What it means
BOT_API_CREATE_LIMIT_ERROR is thrown by createBotApi when redisUtil.tryLock(PUBLISH_API + uid, 3000, uuid) fails — another publish-API operation for the same uid already holds the distributed lock (or the lock couldn't be acquired within 3 seconds). It acts as a concurrency guard so one user can't run parallel API-publish flows.
Solutions
- Retry after the in-flight publish finishes (lock auto-expires after TTL or is released in finally).
- Debounce/disable the publish button on the client to prevent double submission.
- If locks leak repeatedly, ensure unlock in finally (it is) and consider shortening TTL or adding lock ownership checks.
- Check Redis health — latency over ~3s causes false lock conflicts.
Example fix
// before
publishApiService.createBotApi(vo, request, uid, spaceId); // throws if lock held
// after
boolean acquired = false;
for (int i = 0; i < 3 && !acquired; i++) {
try {
publishApiService.createBotApi(vo, request, uid, spaceId);
acquired = true;
} catch (BusinessException e) {
if (!"BOT_API_CREATE_LIMIT_ERROR".equals(e.getCode())) throw e;
Thread.sleep(3000); // wait for prior publish to release lock
}
} Defensive patterns
Strategy: retry
Try / catch
try { publishApiService.createBotApi(vo, request, uid, spaceId); }
catch (BusinessException e) {
if (e.getCode() == ResponseEnum.BOT_API_CREATE_LIMIT_ERROR) { retryAfterDelay(3000); }
else throw e;
} Prevention
- Disable the publish button while a request is in flight (debounce).
- Keep lock TTL comfortably above worst-case publish duration.
- Monitor Redis latency; slow Redis causes spurious lock conflicts.
- Ensure unlock always runs in finally (it does here).
When it happens
Trigger: Calling createBotApi while a previous createBotApi for the same uid is still in progress; a crashed request left the lock held until TTL expiry; network latency making the 3000ms wait elapse; rapid double-click submitting two requests.
Common situations: User double-submits the publish form; retry storm after a slow publish; Redis lock leak from an instance killed mid-operation (lock persists up to TTL).
Related errors
- LONG_CONTENT_FILE_NUM_OUT_LIMIT
- Timed out acquiring distributed lock, please try again later
- Distributed lock acquisition timeout, please try again later
- RELEASE_FAILED
- REDIS_CONNECTION_ERROR
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/64ddbeb2456ef815.
Report an issue: GitHub.
Appendix: source
Thrown at console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/publish/impl/PublishApiServiceImpl.java:143
@Override
@Transactional(rollbackFor = Exception.class)
public BotApiInfoDTO createBotApi(CreateBotApiVo createBotApiVo, HttpServletRequest request, String uid) {
return createBotApi(createBotApiVo, request, uid, SpaceInfoUtil.getSpaceId());
}
@Override
@Transactional(rollbackFor = Exception.class)
public BotApiInfoDTO createBotApi(CreateBotApiVo createBotApiVo, HttpServletRequest request, String uid, Long spaceId) {
String uuid = UUID.randomUUID().toString();
ChatBotBase botBase = chatBotDataService.findOne(uid, createBotApiVo.getBotId(), spaceId);
AppMst appMst = appMstService.getByAppId(uid, createBotApiVo.getAppId());
if (Objects.isNull(botBase) || Objects.isNull(appMst)) {
throw new BusinessException(ResponseEnum.USER_APP_ID_NOT_EXISTE);
}
if (!redisUtil.tryLock(PUBLISH_API + uid, 3000, uuid)) {
throw new BusinessException(ResponseEnum.BOT_API_CREATE_LIMIT_ERROR);
}
try {
List<Integer> maasSupportedVersions = List.of(BotVersionEnum.WORKFLOW.getVersion());
if (maasSupportedVersions.contains(botBase.getVersion())) {
return createMaasApi(uid, appMst, botBase, spaceId, request);
} else {
throw new BusinessException(ResponseEnum.BOT_TYPE_NOT_SUPPORT);
}
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
log.error("PublishApiServiceImpl.createBotApi : create Bot api error, request: {}", createBotApiVo, e);
throw new BusinessException(ResponseEnum.BOT_API_CREATE_ERROR);
} finally {
redisUtil.unlock(PUBLISH_API + uid, uuid);
}
}View on GitHub (pinned to 5e758547a8)