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
- Check DB connectivity/constraint errors in logs immediately before the save failure
- Handle the exception with compensation: call protocol delete for nFlowId so no orphan core flow remains
- Check for duplicate clone requests racing on the same source id
- 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
- Monitor DB connectivity/pool saturation around clone-heavy operations
- Make clone idempotent or add unique request ids to avoid racing duplicates
- Run schema migrations before deploying clone-dependent code
- Add compensation logic that deletes core flows when local save fails
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)