{"record":{"id":"c8d54edaa3df3c53","repo":"iflytek/astron-agent","slug":"chat-tree-error","errorCode":"CHAT_TREE_ERROR","errorMessage":"CHAT_TREE_ERROR","messagePattern":"CHAT_TREE_ERROR","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/chat/impl/ChatRestartServiceImpl.java","lineNumber":43,"sourceCode":"    private ChatListDataService chatListDataService;\n\n    @Autowired\n    private ChatListService chatListService;\n\n    /**\n     * @param rootChatId Root chat ID\n     * @param uid User ID\n     * @param chatListName Chat list name\n     * @return Returns a new chat list creation response\n     * @throws BusinessException Thrown when chat tree index is empty\n     */\n    @Override\n    @Transactional(rollbackFor = Exception.class)\n    public ChatListCreateResponse createNewTreeIndexByRootChatId(Long rootChatId, String uid, String chatListName) {\n        // Retrieve the tree\n        List<ChatTreeIndex> chatTreeIndexList = chatListDataService.findChatTreeIndexByChatIdOrderById(rootChatId);\n        if (CollectionUtil.isEmpty(chatTreeIndexList)) {\n            throw new BusinessException(ResponseEnum.CHAT_TREE_ERROR);\n        }\n\n        // Regenerate a chatId\n        ChatListCreateResponse chatListCreateResponse = chatListService.createChatListForRestart(uid, chatListName, null, chatTreeIndexList.getFirst().getChildChatId());\n        ChatTreeIndex chatTreeIndexLatest = chatTreeIndexList.getFirst();\n        if (chatListCreateResponse.getId().equals(chatTreeIndexLatest.getChildChatId())) {\n            return chatListCreateResponse;\n        }\n\n        ChatTreeIndex chatTreeIndex = ChatTreeIndex.builder()\n                .rootChatId(chatTreeIndexLatest.getRootChatId())\n                .parentChatId(chatTreeIndexLatest.getChildChatId())\n                .childChatId(chatListCreateResponse.getId())\n                .uid(uid)\n                .build();\n        chatListDataService.createChatTreeIndex(chatTreeIndex);\n        return chatListCreateResponse;\n    }","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/chat/impl/ChatRestartServiceImpl.java#L25-L61","documentation":"createNewTreeIndexByRootChatId restarts a chat by loading the ChatTreeIndex rows for the root chatId and rebuilding a new tree. If no tree index rows exist for that rootChatId, there is nothing to restart from, so it throws CHAT_TREE_ERROR inside a transaction (which rolls back any work).","triggerScenarios":"Calling createNewTreeIndexByRootChatId with a rootChatId that has no chat_tree_index rows — e.g. the chat was never branched, the tree rows were deleted, or an incorrect/non-root chatId is passed.","commonSituations":"Frontend passes the current (child) chatId instead of the root chatId; the conversation tree was cleaned up by a data-retention job; restarting a brand-new chat that has no branch tree; a bug elsewhere failed to persist tree index rows when the tree was created.","solutions":["Verify the chatId passed is the tree's root chatId, not a child/branch chatId.","Query chat_tree_index for the chatId to confirm rows exist before attempting a restart.","Check whether a cleanup/retention job deleted the tree rows; restore or recreate the tree.","Guard the UI so the restart action is only enabled for chats that actually have a branch tree."],"exampleFix":"// before\nchatRestartService.createNewTreeIndexByRootChatId(currentChatId, uid, name);\n// after\nList<ChatTreeIndex> tree = chatListDataService.findChatTreeIndexByChatIdOrderById(rootChatId);\nif (tree.isEmpty()) {\n    throw new BusinessException(ResponseEnum.CHAT_TREE_ERROR); // handle in caller before restart\n}\nchatRestartService.createNewTreeIndexByRootChatId(rootChatId, uid, name);","handlingStrategy":"validation","validationCode":"List<ChatTreeIndex> tree = chatListDataService.findChatTreeIndexByChatIdOrderById(rootChatId);\nboolean canRestart = tree != null && !tree.isEmpty();\nif (!canRestart) {\n    // disable restart or create a fresh chat instead\n}","typeGuard":"boolean hasTree(Long rootChatId) {\n    List<ChatTreeIndex> tree = chatListDataService.findChatTreeIndexByChatIdOrderById(rootChatId);\n    return tree != null && !tree.isEmpty();\n}","tryCatchPattern":"try {\n    chatRestartService.createNewTreeIndexByRootChatId(rootChatId, uid, name);\n} catch (BusinessException e) {\n    if (ResponseEnum.CHAT_TREE_ERROR.equals(e.getResponseEnum())) {\n        // fall back to creating a brand-new chat list\n    }\n}","preventionTips":["Always pass the tree's root chatId, resolved from the tree index, not a child chatId.","Only enable the restart UI action for chats with an existing branch tree.","Ensure tree index rows are persisted atomically when a tree is created, and audit retention jobs that prune them."],"tags":["java","chat","tree","data-integrity"],"backgroundTag":"empty-result-set","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}