{"record":{"id":"33a201675a394617","repo":"apolloconfig/apollo","slug":"cluster-not-unique","errorCode":null,"errorMessage":"cluster not unique","messagePattern":"cluster not unique","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ClusterService.java","lineNumber":93,"sourceCode":"\n    return clusters;\n  }\n\n  @Transactional\n  public Cluster saveWithInstanceOfAppNamespaces(Cluster entity) {\n\n    Cluster savedCluster = saveWithoutInstanceOfAppNamespaces(entity);\n\n    namespaceService.instanceOfAppNamespaces(savedCluster.getAppId(), savedCluster.getName(),\n        savedCluster.getDataChangeCreatedBy());\n\n    return savedCluster;\n  }\n\n  @Transactional\n  public Cluster saveWithoutInstanceOfAppNamespaces(Cluster entity) {\n    if (!isClusterNameUnique(entity.getAppId(), entity.getName())) {\n      throw new BadRequestException(\"cluster not unique\");\n    }\n    entity.setId(0);// protection\n    Cluster cluster = clusterRepository.save(entity);\n\n    auditService.audit(Cluster.class.getSimpleName(), cluster.getId(), Audit.OP.INSERT,\n        cluster.getDataChangeCreatedBy());\n\n    return cluster;\n  }\n\n  @Transactional\n  public void delete(long id, String operator) {\n    Cluster cluster = clusterRepository.findById(id).orElse(null);\n    if (cluster == null) {\n      throw BadRequestException.clusterNotExists(\"\");\n    }\n\n    // delete linked namespaces","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ClusterService.java#L75-L111","documentation":"A BadRequestException (HTTP 400) thrown from ClusterService.saveWithoutInstanceOfAppNamespaces() when a cluster with the same name already exists for the given appId. The uniqueness check isClusterNameUnique() queries clusterRepository.findByAppIdAndName(). This is the user-facing cluster creation path; a duplicate cluster name within the same app is rejected as a client error (400).","triggerScenarios":"POST to create a cluster (ClusterService.saveWithInstanceOfAppNamespaces or saveWithoutInstanceOfAppNamespaces) with a name that already exists for the same appId. For example, creating cluster 'DC2' when 'DC2' already exists for appId 'myApp'.","commonSituations":"Retried cluster-creation request after a timeout; two operators creating the same cluster concurrently; a migration script re-run; attempting to recreate a cluster that was soft-deleted but whose uniqueness-check row still exists.","solutions":["Check isClusterNameUnique(appId, clusterName) before calling save.","If the cluster already exists, retrieve and use it.","Ensure cluster-creation requests are not retried without checking existence."],"exampleFix":"// before: unconditional creation\nclusterService.saveWithInstanceOfAppNamespaces(newCluster);\n\n// after: guard with uniqueness check\nif (clusterService.isClusterNameUnique(appId, clusterName)) {\n    clusterService.saveWithInstanceOfAppNamespaces(newCluster);\n} else {\n    return clusterService.findOne(appId, clusterName);\n}","handlingStrategy":"validation","validationCode":"// Check cluster name uniqueness before creating\nif (clusterService.isClusterNameUnique(appId, clusterName)) {\n    clusterService.saveWithInstanceOfAppNamespaces(newCluster);\n} else {\n    return clusterService.findOne(appId, clusterName);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call isClusterNameUnique() before any cluster creation.","Make cluster-creation flows idempotent by returning the existing cluster.","Avoid concurrent cluster-creation requests for the same appId+name."],"tags":["cluster","duplicate","bad-request","apollo-biz"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}