{"record":{"id":"1a2a6314a61b93c3","repo":"iflytek/astron-agent","slug":"internal-server-error-1a2a63","errorCode":"INTERNAL_SERVER_ERROR","errorMessage":"INTERNAL_SERVER_ERROR","messagePattern":"INTERNAL_SERVER_ERROR","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"critical","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowService.java","lineNumber":1203,"sourceCode":"        replica.setId(null);\n        if (spaceId != null)\n            replica.setSpaceId(spaceId);\n        replica.setUid(uid);\n        replica.setName(cloneName);\n        Date now = new Date();\n        replica.setCreateTime(now);\n        replica.setUpdateTime(now);\n        replica.setFlowId(nFlowId);\n        if (data != null)\n            replica.setData(JSON.toJSONString(data));\n        if (src.getPublishedData() != null) {\n            replica.setPublishedData(JSON.toJSONString(handleDataClone(nFlowId, src.getPublishedData())));\n        }\n        replica.setAppUpdatable(false);\n        replica.setOrder(DEFAULT_ORDER);\n        replica.setExt(null);\n        if (!save(replica)) {\n            throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);\n        }\n        Integer botId = openPlatformService.syncWorkflowClone(uid, src.getId(), replica.getId(), replica.getFlowId(), spaceId);\n        JSONObject result = new JSONObject();\n        if (result != null) {\n            JSONObject ext = new JSONObject();\n            ext.put(JSON_KEY_BOT_ID, Integer.valueOf(String.valueOf(botId)));\n            replica.setName(result.getString(\"botName\"));\n            replica.setExt(ext.toJSONString());\n            updateById(replica);\n            if (Objects.equals(src.getType(), BotTypeEnum.TALK.getType())) {\n                WorkflowConfig workflowConfig = workflowConfigMapper.selectOne(new LambdaQueryWrapper<WorkflowConfig>()\n                        .eq(WorkflowConfig::getFlowId, src.getFlowId())\n                        .eq(WorkflowConfig::getVersionNum, \"-1\")\n                        .eq(WorkflowConfig::getDeleted, false));\n                workflowConfig.setId(null);\n                workflowConfig.setFlowId(replica.getFlowId());\n                workflowConfig.setBotId(botId);\n                workflowConfig.setCreatedTime(new Date());","sourceCodeStart":1185,"sourceCodeEnd":1221,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowService.java#L1185-L1221","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nif (!save(replica)) {\n    throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);\n}\n// after\nif (!save(replica)) {\n    log.error(\"clone replica save failed, srcId={}, flowId={}\", src.getId(), replica.getFlowId());\n    protocolDeleteQuietly(replica.getFlowId()); // compensate: remove orphan core flow\n    throw new BusinessException(ResponseEnum.INTERNAL_SERVER_ERROR);\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight: DB reachable before starting clone\ntry (Connection c = dataSource.getConnection()) {\n    if (!c.isValid(2)) throw new IllegalStateException(\"database unreachable\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    workflowService.cloneForXfYun(id, spaceId);\n} catch (BusinessException e) {\n    if (\"INTERNAL_SERVER_ERROR\".equals(e.getCode())) {\n        log.error(\"clone replica DB save failed; check for orphan core flow/bot\", e);\n        compensateOrphanClone(id); // delete core flow via protocol delete\n    } else throw e;\n}","preventionTips":["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"],"tags":["workflow","database","clone"],"backgroundTag":"database-write-failed","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}