{"record":{"id":"fdb5994a8103800a","repo":"floci-io/floci","slug":"conflictexception-fdb599","errorCode":"ConflictException","errorMessage":"Channel namespace already exists: \" + name","messagePattern":"Channel namespace already exists: \" \\+ name","errorType":"exception","errorClass":"AwsException","httpStatus":409,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/appsync/AppSyncService.java","lineNumber":784,"sourceCode":"\n    public void disassociateApi(String domainName) {\n        getDomainName(domainName);\n        associationStore.get(domainName).ifPresent(apiId -> assertSchemaNotBusy(apiId));\n        associationStore.delete(domainName);\n    }\n\n    // ──────────────────────────── Channel Namespaces ────────────────────────────\n\n    public ChannelNamespace createChannelNamespace(String apiId, Map<String, Object> request) {\n        assertSchemaNotBusy(apiId);\n        getGraphqlApi(apiId);\n        String name = (String) request.get(\"name\");\n        if (name == null || name.isBlank()) {\n            throw new AwsException(\"BadRequestException\", \"A channel namespace name is required\", 400);\n        }\n        String nsKey = apiKey(apiId, name);\n        if (channelNamespaceStore.get(nsKey).isPresent()) {\n            throw new AwsException(\"ConflictException\",\n                \"Channel namespace already exists: \" + name, 409);\n        }\n        ChannelNamespace ns = new ChannelNamespace();\n        ns.setName(name);\n        ns.setApiId(apiId);\n        ns.setDescription((String) request.get(\"description\"));\n        ns.setChannelNamespaceArn(regionResolver.buildArn(\"appsync\", regionResolver.getDefaultRegion(),\n            \"apis/\" + apiId + \"/channelNamespaces/\" + name));\n        ns.setCodeHandlers((String) request.get(\"codeHandlers\"));\n        ns.setCreated(System.currentTimeMillis());\n        ns.setLastModified(System.currentTimeMillis());\n        channelNamespaceStore.put(nsKey, ns);\n        return ns;\n    }\n\n    public ChannelNamespace getChannelNamespace(String apiId, String name) {\n        return channelNamespaceStore.get(apiKey(apiId, name))\n                .orElseThrow(() -> new AwsException(\"NotFoundException\",","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/appsync/AppSyncService.java#L766-L802","documentation":"Thrown by createChannelNamespace when a namespace with the same name already exists under the API (key apiKey(apiId, name) present in channelNamespaceStore). Unlike most create duplicates here, this is a ConflictException with HTTP 409, reflecting the newer Event API semantics.","triggerScenarios":"Calling createChannelNamespace twice with the same name on the same apiId; provisioning scripts that create the 'default' namespace on every run.","commonSituations":"Idempotent deployment tooling; retrying after a network error where the first create actually succeeded; shared emulator state across tests.","solutions":["Use the update path (updateChannelNamespace) if the namespace already exists","Delete the namespace before re-creating it","List namespaces first (listChannelNamespaces) and skip existing ones"],"exampleFix":"// before\nappSync.createChannelNamespace(apiId, Map.of(\"name\", \"default\")); // 2nd run -> 409\n\n// after\nboolean exists = appSync.listChannelNamespaces(apiId, null, null).getItems().stream()\n        .anyMatch(ns -> ns.getName().equals(\"default\"));\nif (!exists) {\n    appSync.createChannelNamespace(apiId, Map.of(\"name\", \"default\"));\n}","handlingStrategy":"try-catch","validationCode":"boolean exists = appSync.listChannelNamespaces(apiId, null, null).getItems().stream()\n        .anyMatch(ns -> ns.getName().equals(name));\nif (!exists) appSync.createChannelNamespace(apiId, request);","typeGuard":null,"tryCatchPattern":"try {\n    appSync.createChannelNamespace(apiId, request);\n} catch (AwsException e) {\n    if (\"ConflictException\".equals(e.getCode()) && e.getMessage().contains(\"already exists\")) {\n        appSync.updateChannelNamespace(apiId, name, request); // upsert\n    } else throw e;\n}","preventionTips":["Treat ConflictException 409 on create as 'already provisioned' and switch to update","Use stable namespace names so retries converge instead of multiplying"],"tags":["appsync","channel-namespace","duplicate","conflict-409","event-api"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}