iflytek/astron-agent · critical · BusinessException

INTERNAL_SERVER_ERROR

INTERNAL_SERVER_ERROR

Error message

INTERNAL_SERVER_ERROR

What it means

In the cloneForXfYun path (open-platform bot clone), after the core protocol add succeeds, the replica Workflow row is inserted locally with save(replica). If MyBatis-Plus returns false, the local DB write failed and INTERNAL_SERVER_ERROR is thrown. This is a local persistence failure, not an upstream one — the core flow may already exist, leaving an orphaned flow if not compensated.

Solutions

  1. Check DB connectivity/constraint errors in logs immediately before the save failure
  2. Handle the exception with compensation: call protocol delete for nFlowId so no orphan core flow remains
  3. Check for duplicate clone requests racing on the same source id
  4. Verify schema version and required columns exist for the replica insert

Example fix

// before
if (!save(replica)) {
    throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);
}
// after
if (!save(replica)) {
    log.error("clone replica save failed, srcId={}, flowId={}", src.getId(), replica.getFlowId());
    protocolDeleteQuietly(replica.getFlowId()); // compensate: remove orphan core flow
    throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: DB reachable before starting clone
try (Connection c = dataSource.getConnection()) {
    if (!c.isValid(2)) throw new IllegalStateException("database unreachable");
}

Try / catch

try {
    workflowService.cloneForXfYun(id, spaceId);
} catch (BusinessException e) {
    if ("INTERNAL_SERVER_ERROR".equals(e.getCode())) {
        log.error("clone replica DB save failed; check for orphan core flow/bot", e);
        compensateOrphanClone(id); // delete core flow via protocol delete
    } else throw e;
}

Prevention

When it happens

Trigger: cloneForXfYun: replica.setAppUpdatable(false), order, ext cleared, then save(replica) returns false — DB connection failure, constraint violation, unique key conflict on the new flowId/id, or table unavailable.

Common situations: Database outage or pool exhaustion during clone, unique index collision (e.g. duplicated clone call in a race), schema migration mismatch between console and DB.

Related errors


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

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowService.java:1203

        replica.setId(null);
        if (spaceId != null)
            replica.setSpaceId(spaceId);
        replica.setUid(uid);
        replica.setName(cloneName);
        Date now = new Date();
        replica.setCreateTime(now);
        replica.setUpdateTime(now);
        replica.setFlowId(nFlowId);
        if (data != null)
            replica.setData(JSON.toJSONString(data));
        if (src.getPublishedData() != null) {
            replica.setPublishedData(JSON.toJSONString(handleDataClone(nFlowId, src.getPublishedData())));
        }
        replica.setAppUpdatable(false);
        replica.setOrder(DEFAULT_ORDER);
        replica.setExt(null);
        if (!save(replica)) {
            throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);
        }
        Integer botId = openPlatformService.syncWorkflowClone(uid, src.getId(), replica.getId(), replica.getFlowId(), spaceId);
        JSONObject result = new JSONObject();
        if (result != null) {
            JSONObject ext = new JSONObject();
            ext.put(JSON_KEY_BOT_ID, Integer.valueOf(String.valueOf(botId)));
            replica.setName(result.getString("botName"));
            replica.setExt(ext.toJSONString());
            updateById(replica);
            if (Objects.equals(src.getType(), BotTypeEnum.TALK.getType())) {
                WorkflowConfig workflowConfig = workflowConfigMapper.selectOne(new LambdaQueryWrapper<WorkflowConfig>()
                        .eq(WorkflowConfig::getFlowId, src.getFlowId())
                        .eq(WorkflowConfig::getVersionNum, "-1")
                        .eq(WorkflowConfig::getDeleted, false));
                workflowConfig.setId(null);
                workflowConfig.setFlowId(replica.getFlowId());
                workflowConfig.setBotId(botId);
                workflowConfig.setCreatedTime(new Date());

View on GitHub (pinned to 5e758547a8)