{"record":{"id":"72aa7e264376ae61","repo":"floci-io/floci","slug":"servicealreadyexists","errorCode":"ServiceAlreadyExists","errorMessage":"A service named \\\"{}\\\" already exists.","messagePattern":"A service named \\\\\"(.+?)\\\\\" already exists\\.","errorType":"exception","errorClass":"AwsException","httpStatus":400,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/cloudmap/CloudMapService.java","lineNumber":178,"sourceCode":"                                 String healthCheckCustomConfig, String type,\n                                 Map<String, String> tags, String region) {\n        if (name == null || name.isBlank()) {\n            throw new AwsException(\"InvalidInput\", \"Service name is required.\", 400);\n        }\n        String resolvedNamespaceId = namespaceId;\n        if (dnsConfig != null && resolvedNamespaceId == null) {\n            // DnsConfig may carry the namespace id when the top-level field is absent.\n            resolvedNamespaceId = dnsConfigNamespaceId(dnsConfig);\n        }\n        if (resolvedNamespaceId != null) {\n            requireNamespace(resolvedNamespaceId);\n        }\n        final String nsId = resolvedNamespaceId;\n        boolean exists = scan(serviceStore).stream()\n                .anyMatch(s -> region.equals(s.getRegion()) && name.equals(s.getName())\n                        && java.util.Objects.equals(nsId, s.getNamespaceId()));\n        if (exists) {\n            throw new AwsException(\"ServiceAlreadyExists\",\n                    \"A service named \\\"\" + name + \"\\\" already exists.\", 400);\n        }\n        Service service = new Service();\n        service.setId(\"srv-\" + randomId(20));\n        service.setName(name);\n        service.setNamespaceId(nsId);\n        service.setDescription(description);\n        service.setDnsConfig(dnsConfig);\n        service.setHealthCheckConfig(healthCheckConfig);\n        service.setHealthCheckCustomConfig(healthCheckCustomConfig);\n        service.setType(resolveServiceType(type, dnsConfig));\n        service.setCreatorRequestId(creatorRequestId != null ? creatorRequestId : UUID.randomUUID().toString());\n        service.setCreateDate(Instant.now());\n        service.setRegion(region);\n        service.setInstanceCount(0);\n        service.setRevision(0L);\n        if (tags != null) {\n            service.setTags(tags);","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/cloudmap/CloudMapService.java#L160-L196","documentation":"Thrown when CreateService would create a second service with the same name in the same namespace and region. CloudMapService scans the service store for (region, name, namespaceId) equality — namespace id may come from the top-level field or be extracted from DnsConfig — and raises ServiceAlreadyExists before constructing the new service. AWS enforces the same uniqueness: service names are unique within a namespace.","triggerScenarios":"Running CreateService twice with the same Name and NamespaceId in the same region; re-running an idempotent-looking deployment script without cleanup; passing a different namespace id casing/format (e.g. id pulled from DnsConfig instead of the top-level field) and expecting it to be a distinct service — the emulator treats a matching resolved namespace id as a collision.","commonSituations":"CI pipelines that provision Cloud Map services on every run against a persistent Floci storage mode; drift between what a previous run created and what the script assumes; renaming logic that creates-then-deletes and fails halfway.","solutions":["Before creating, call ListServices filtered by namespace and check whether the name already exists; reuse it instead of creating.","Delete the stale service (DeregisterInstance first, then DeleteService) if it is leftover from a previous run.","Suffix generated names (e.g. orders-service-<env>-<build>) when concurrent runs may collide.","If the collision is unexpected, verify which namespace id the request resolves to — DnsConfig can carry one when the top-level NamespaceId is absent."],"exampleFix":"// before\nclient.createService(b -> b.name(\"orders\").namespaceId(nsId));\n\n// after\nboolean exists = client.listServices(b -> b.namespaceId(nsId)).services().stream()\n    .anyMatch(s -> s.name().equals(\"orders\"));\nif (!exists) {\n    client.createService(b -> b.name(\"orders\").namespaceId(nsId));\n}","handlingStrategy":"validation","validationCode":"boolean exists = client.listServices(b -> b.namespaceId(nsId)).services().stream()\n    .anyMatch(s -> s.name().equals(name));\nif (exists) { /* reuse existing service instead of creating */ }","typeGuard":null,"tryCatchPattern":"try {\n    client.createService(req);\n} catch (ServiceAlreadyExistsException e) {\n    // adopt the existing service: fetch it and continue\n}","preventionTips":["Make provisioning scripts idempotent: list-before-create with a stable naming scheme.","Keep namespace ids stable across runs so uniqueness checks compare like with like."],"tags":["aws","cloudmap","servicediscovery","duplicate","conflict"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}