{"record":{"id":"4c5c1eb2a3d56fe5","repo":"iflytek/astron-agent","slug":"repo-folder-not-exist","errorCode":"REPO_FOLDER_NOT_EXIST","errorMessage":"REPO_FOLDER_NOT_EXIST","messagePattern":"REPO_FOLDER_NOT_EXIST","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/repo/FileInfoV2Service.java","lineNumber":2301,"sourceCode":"    public void deleteFile(Long id) {\n        fileDirectoryTreeService.remove(Wrappers.lambdaQuery(FileDirectoryTree.class).eq(FileDirectoryTree::getFileId, id));\n        List<Long> ids = new ArrayList<>();\n        ids.add(id);\n        knowledgeService.deleteDoc(ids);\n    }\n\n\n    /**\n     * Delete folder and all its contents recursively\n     *\n     * @param id folder ID to delete\n     * @throws BusinessException if folder does not exist or repository access is denied\n     */\n    @Transactional\n    public void deleteFolder(Long id) {\n        FileDirectoryTree fileDirectoryTree = fileDirectoryTreeService.getById(id);\n        if (fileDirectoryTree == null || fileDirectoryTree.getIsFile() != 0) {\n            throw new BusinessException(ResponseEnum.REPO_FOLDER_NOT_EXIST);\n        }\n        Repo repo = repoService.getById(fileDirectoryTree.getAppId());\n        if (repo != null) {\n            dataPermissionCheckTool.checkRepoBelong(repo);\n        }\n        // Recursively find all files and directory objects under the current folder\n        List<FileDirectoryTree> dirList = new ArrayList<>();\n        List<FileDirectoryTree> fileList = new ArrayList<>();\n        this.recursiveFindChildPath(fileDirectoryTree.getAppId(), id, dirList, fileList);\n        Set<Long> delIdSet = new HashSet<>();\n        delIdSet.add(id);\n        for (FileDirectoryTree directoryTree : dirList) {\n            delIdSet.add(directoryTree.getId());\n        }\n        List<Long> delDocIdList = new ArrayList<>();\n        for (FileDirectoryTree directoryTree : fileList) {\n            delIdSet.add(directoryTree.getId());\n            delDocIdList.add(directoryTree.getFileId());","sourceCodeStart":2283,"sourceCodeEnd":2319,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/repo/FileInfoV2Service.java#L2283-L2319","documentation":"BusinessException(REPO_FOLDER_NOT_EXIST) thrown at the start of deleteFolder(Long id) when the fileDirectoryTree record does not exist or its isFile flag is not 0 (i.e. it is a file, not a folder). The method requires the id to reference a directory node before it recursively collects and deletes its children.","triggerScenarios":"Calling deleteFolder with: an id already deleted by another user/session, a non-existent id, or the id of a file node (isFile == 1) instead of a folder.","commonSituations":"Folder removed concurrently in another tab while the user clicks delete; frontend mixing up file and folder ids in the tree component; retry of a previously successful delete.","solutions":["Confirm the id refers to a directory node with isFile == 0 before invoking deleteFolder.","Use the file-delete endpoint instead when the target is a file node.","Handle idempotency in the client: treat 'folder not exist' on delete as already-done and refresh the tree.","Check tenant/space: the record may exist but in a different workspace's tree."],"exampleFix":"// before\nawait repoApi.deleteFolder(selectedId);\n// after: validate node type first\nconst node = await repoApi.getTreeNode(selectedId);\nif (!node || node.isFile !== 0) return; // nothing to delete\nawait repoApi.deleteFolder(selectedId);","handlingStrategy":"validation","validationCode":"const node = await fileApi.getTreeNode(id);\nif (!node || node.isFile !== 0) {\n  throw new Error(`id ${id} is not a folder node`);\n}","typeGuard":"function isFolderNode(node) {\n  return node != null && node.isFile === 0;\n}","tryCatchPattern":"try {\n  await repoApi.deleteFolder(id);\n} catch (e) {\n  if (e.code === 'REPO_FOLDER_NOT_EXIST') {\n    await refreshTree(); // already gone\n    return;\n  }\n  throw e;\n}","preventionTips":["Confirm isFile === 0 before folder deletes; route file nodes to the file API.","Treat repeated delete failures on the same id as stale state and refresh.","Guard against concurrent deletes with per-node locks or disable-after-click."],"tags":["java","not-found","validation","spring-boot"],"backgroundTag":"entity-not-found","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"}