iflytek/astron-agent · error · BusinessException

BOT_CHAIN_SUBMIT_ERROR

BOT_CHAIN_SUBMIT_ERROR

Error message

BOT_CHAIN_SUBMIT_ERROR

What it means

BusinessException with code BOT_CHAIN_SUBMIT_ERROR thrown by chatWorkflowBot when userLangChainDataService.findOneByBotId(botId) returns null — i.e. no workflow (LangChain) binding exists for the bot, so there is no flowId to submit the chat request to.

Solutions

  1. Verify the botId is correct and that the bot is actually a workflow-type bot.
  2. Re-fetch the bot list to clear stale botIds and retry with a valid one.
  3. Re-publish/bind the workflow to the bot so a UserLangChainInfo record with a flowId exists.
  4. Check the database for a missing user_lang_chain_info row for this botId and restore the binding if it was lost.

Example fix

// before: chat with any bot id
await chatWorkflowBot({ botId: someId, ask });
// after: only workflow bots support this endpoint
const bot = await getBot(someId);
if (!bot || bot.type !== 'workflow') throw new Error('Bot has no workflow bound');
await chatWorkflowBot({ botId: someId, ask });
Defensive patterns

Strategy: validation

Validate before calling

const bot = await getBot(botId);
if (!bot || !bot.flowId) throw new Error('Bot has no workflow binding; cannot chat');

Type guard

function isWorkflowBot(bot) { return bot != null && typeof bot.flowId === 'string' && bot.flowId.length > 0; }

Try / catch

try { await chatWorkflowBot({ botId, ask }); } catch (e) { if (e.code === 'BOT_CHAIN_SUBMIT_ERROR') { await refreshBotList(); notify('This bot has no workflow bound'); } else throw e; }

Prevention

When it happens

Trigger: Sending a chat request to a botId that has no associated workflow record: the bot was created as a basic bot, the workflow binding was deleted, the wrong botId was passed, or the binding row is missing/corrupt in the database.

Common situations: Client caching a stale botId after the bot was deleted or converted; bots imported/copied without their workflow binding; race between bot deletion and an in-flight chat request; environment mismatch where the bot exists in one DB but its chain record is in another.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/cae00e683b727480. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/commons/src/main/java/com/iflytek/astron/console/commons/service/workflow/impl/WorkflowBotChatServiceImpl.java:124

    public void chatWorkflowBot(ChatBotReqDto chatBotReqDto, SseEmitter sseEmitter, String sseId, String workflowOperation, String workflowVersion) {
        String uid = chatBotReqDto.getUid();
        Long chatId = chatBotReqDto.getChatId();
        String ask = chatBotReqDto.getAsk();
        String url = chatBotReqDto.getUrl();
        Integer botId = chatBotReqDto.getBotId();

        if (StrUtil.isBlank(ask)) {
            log.warn("Rejecting workflow chat request with empty user input, uid: {}, chatId: {}, botId: {}",
                    uid, chatId, botId);
            throw new BusinessException(ResponseEnum.PARAMETER_ERROR);
        }

        JSONObject inputs = new JSONObject();
        inputs.put("AGENT_USER_INPUT", ask);

        UserLangChainInfo userLangChainInfo = userLangChainDataService.findOneByBotId(botId);
        if (userLangChainInfo == null) {
            throw new BusinessException(ResponseEnum.BOT_CHAIN_SUBMIT_ERROR);
        }
        String flowId = userLangChainInfo.getFlowId();
        String effectiveWorkflowVersion = resolveWorkflowVersion(botId, flowId, workflowVersion);
        // Record current question
        ChatReqRecords chatReqRecords = new ChatReqRecords();
        chatReqRecords.setChatId(chatId);
        chatReqRecords.setUid(uid);
        chatReqRecords.setMessage(ask);
        chatReqRecords.setClientType(0);
        chatReqRecords.setCreateTime(LocalDateTime.now());
        chatReqRecords.setUpdateTime(LocalDateTime.now());
        chatReqRecords.setNewContext(1);
        chatReqRecords = chatDataService.createRequest(chatReqRecords);
        Long reqId = chatReqRecords.getId();

        JSONObject extraInputs = JSONObject.parseObject(userLangChainInfo.getExtraInputs());

        // Handle multi-file parameter type

View on GitHub (pinned to 5e758547a8)