{"record":{"id":"414981aa0af0f7ed","repo":"floci-io/floci","slug":"resourceinuse-414981","errorCode":"ResourceInUse","errorMessage":"Cannot delete this resource because it is in use.","messagePattern":"Cannot delete this resource because it is in use\\.","errorType":"exception","errorClass":"AwsException","httpStatus":409,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontService.java","lineNumber":1083,"sourceCode":"        validateKeyGroup(updated);\n        validateUniqueKeyGroupName(updated.getName(), id);\n        updated.setId(id);\n        updated.setLastModifiedTime(Instant.now());\n        updated.setEtag(UUID.randomUUID().toString());\n        keyGroupStore.put(id, updated);\n        return updated;\n    }\n\n    public synchronized void deleteKeyGroup(String id, String ifMatch) {\n        KeyGroup existing = getKeyGroup(id);\n        if (!existing.getEtag().equals(ifMatch)) {\n            throw new AwsException(\n                    \"PreconditionFailed\",\n                    \"The precondition in one or more request-header fields evaluated to false.\",\n                    412);\n        }\n        if (keyGroupInUse(id)) {\n            throw new AwsException(\n                    \"ResourceInUse\",\n                    \"Cannot delete this resource because it is in use.\",\n                    409);\n        }\n        keyGroupStore.delete(id);\n    }\n\n    private void validateUniqueKeyGroupName(String name, String excludedId) {\n        boolean duplicate = keyGroupStore.scan(group -> true).stream()\n                .anyMatch(group -> !Objects.equals(excludedId, group.getId())\n                        && Objects.equals(name, group.getName()));\n        if (duplicate) {\n            throw new AwsException(\n                    \"KeyGroupAlreadyExists\",\n                    \"A key group with this name already exists.\",\n                    409);\n        }\n    }","sourceCodeStart":1065,"sourceCodeEnd":1101,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontService.java#L1065-L1101","documentation":"CloudFrontService.deleteKeyGroup throws ResourceInUse (HTTP 409) when keyGroupInUse(id) determines the group is still referenced by a stored distribution configuration. CloudFront refuses to delete key groups that distributions depend on (trusted key groups on cache behaviors), and the emulator enforces the same guard.","triggerScenarios":"DeleteKeyGroup while any distribution's cache behaviors still list the group in TrustedKeyGroups — commonly deleting the group before the distribution, or after a test re-created a distribution referencing it.","commonSituations":"Teardown in creation order; long-lived emulator state where old distributions from earlier runs still reference the fixture key group; forgetting that UpdateDistribution can re-attach a group.","solutions":["Delete or update distributions that reference the key group first (remove it from TrustedKeyGroups), then delete the group.","Inspect ListDistributions for references before attempting deletion.","In tests, clean up state or use unique names per run so stale distributions cannot hold references."],"exampleFix":"// before\ndeleteKeyGroup(groupId); // 409 while distributions reference it\n\n// after\nfor (Distribution d : distributionsReferencingGroup(groupId)) {\n    deleteDistribution(d.getId());\n}\ndeleteKeyGroup(groupId);","handlingStrategy":"try-catch","validationCode":"boolean keyGroupReferenced(CloudFrontClient client, String groupId) {\n    return client.listDistributions(r -> r.build()).distributionList().items().stream()\n            .anyMatch(d -> distributionBehaviorsTrustGroup(d, groupId));\n}","typeGuard":null,"tryCatchPattern":"try {\n    client.deleteKeyGroup(r -> r.id(groupId).ifMatch(etag));\n} catch (ResourceInUse e) {\n    // strip the group from TrustedKeyGroups on referencing distributions (or delete them), then retry\n}","preventionTips":["Remove key-group references from distributions before group deletion.","Teardown in reverse creation order.","Isolate test fixtures with unique names to avoid cross-run references."],"tags":["cloudfront","key-group","dependency","conflict","aws-emulator"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}