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

  1. Retry after the in-flight publish finishes (lock auto-expires after TTL or is released in finally).
  2. Debounce/disable the publish button on the client to prevent double submission.
  3. If locks leak repeatedly, ensure unlock in finally (it is) and consider shortening TTL or adding lock ownership checks.
  4. 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

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


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)