{"record":{"id":"b40954374b737182","repo":"iflytek/astron-agent","slug":"repo-file-delete-failed","errorCode":"REPO_FILE_DELETE_FAILED","errorMessage":"REPO_FILE_DELETE_FAILED","messagePattern":"REPO_FILE_DELETE_FAILED","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":2250,"sourceCode":"     * @param tag file source tag (Spark RAG or others)\n     * @param repoId repository ID\n     * @param request HTTP servlet request for authentication\n     * @throws BusinessException if file deletion fails or repository access is denied\n     */\n    @Transactional\n    public void deleteFileDirectoryTree(String id, String tag, Long repoId, HttpServletRequest request) {\n        if (ProjectContent.isSparkRagCompatible(tag)) {\n            // Spark Delete\n            String url = apiUrl.getDeleteXinghuoDatasetFileUrl() + \"?datasetId=\" + repoId + \"&fileId=\" + id;\n            HashMap<String, String> header = new HashMap<>();\n            String authorization = request.getHeader(\"Authorization\");\n            if (StringUtils.isNotBlank(authorization)) {\n                header.put(\"Authorization\", authorization);\n            }\n            String resp = OkHttpUtil.get(url, header);\n            JSONObject jsonObject = JSONObject.parseObject(resp);\n            if (jsonObject.get(\"code\") == null || jsonObject.getIntValue(\"code\") != 0) {\n                throw new BusinessException(ResponseEnum.REPO_FILE_DELETE_FAILED);\n            }\n        } else {\n            Repo repo = repoService.getById(repoId);\n            if (repo != null) {\n                dataPermissionCheckTool.checkRepoBelong(repo);\n            }\n\n            Long fileId = Long.valueOf(id);\n            FileDirectoryTree fileDirectoryTree = fileDirectoryTreeService.getById(fileId);\n            if (fileDirectoryTree == null || fileDirectoryTree.getIsFile() != 1) {\n                throw new BusinessException(ResponseEnum.REPO_FILE_NOT_EXIST);\n            }\n\n            fileDirectoryTreeService.removeById(fileId);\n            List<Long> ids = new ArrayList<>();\n            ids.add(fileDirectoryTree.getFileId());\n\n            // Add back billing metrics after deletion","sourceCodeStart":2232,"sourceCodeEnd":2268,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/repo/FileInfoV2Service.java#L2232-L2268","documentation":"BusinessException(REPO_FILE_DELETE_FAILED) thrown when the remote knowledge-service delete call returns a non-zero code or an unparsable/missing code field. The service builds a URL with authorization headers, performs OkHttpUtil.get, parses the JSON response, and treats code != 0 as a failed deletion. The local transaction is aborted so the tree node is not removed while the backend content persists.","triggerScenarios":"Deleting a repo file whose backing knowledge data lives in the remote service: the remote responds with code != 0 (deletion refused, record busy, auth rejected) or returns a body without a 'code' field (HTML error page, gateway timeout body).","commonSituations":"Remote knowledge service down or redeploying; invalid/expired Authorization header forwarded from the client; network gateway returning 502 HTML that fails the code==0 check; remote record already deleted (idempotent delete conflict).","solutions":["Inspect the remote response body (log 'resp') to see the actual code/message returned by the knowledge service.","Verify the Authorization header is valid and not expired; re-authenticate and retry.","Check the remote knowledge service health and whether the target record still exists there.","Retry the delete after the remote service recovers; if it was already deleted remotely, remove the local tree node manually or make the call idempotent."],"exampleFix":"// before: any non-zero code aborts\nif (jsonObject.get(\"code\") == null || jsonObject.getIntValue(\"code\") != 0) {\n    throw new BusinessException(ResponseEnum.REPO_FILE_DELETE_FAILED);\n}\n// after: tolerate already-deleted remote record\nint code = jsonObject.getIntValue(\"code\");\nif (code != 0 && code != REMOTE_ALREADY_DELETED_CODE) {\n    log.error(\"remote delete failed, code={}, resp={}\", code, resp);\n    throw new BusinessException(ResponseEnum.REPO_FILE_DELETE_FAILED);\n}","handlingStrategy":"retry","validationCode":"// pre-check remote reachability before issuing delete\nconst health = await fetch(`${knowledgeBaseUrl}/health`).then(r => r.ok).catch(() => false);\nif (!health) throw new Error('knowledge service unavailable, defer delete');","typeGuard":null,"tryCatchPattern":"try {\n  await repoApi.deleteFile(id);\n} catch (e) {\n  if (e.code === 'REPO_FILE_DELETE_FAILED') {\n    // retry with backoff; remote may be transiently down\n    await retry(() => repoApi.deleteFile(id), { retries: 3, backoffMs: 2000 });\n    return;\n  }\n  throw e;\n}","preventionTips":["Monitor remote knowledge-service availability before delete operations.","Ensure the Authorization header is fresh and forwarded correctly.","Log the remote response body on failure for quick diagnosis.","Make remote deletes idempotent to tolerate already-deleted records."],"tags":["java","http","delete","remote-service"],"backgroundTag":"http-error-response","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"}