{"record":{"id":"94d6cc998fd5f2f1","repo":"floci-io/floci","slug":"invalidrequestexception-94d6cc","errorCode":"InvalidRequestException","errorMessage":"Non-empty backup vault cannot be deleted: {vaultName}","messagePattern":"Non-empty backup vault cannot be deleted: (.+?)","errorType":"exception","errorClass":"AwsException","httpStatus":400,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/backup/BackupService.java","lineNumber":94,"sourceCode":"        vault.setEncryptionKeyArn(encryptionKeyArn);\n        vault.setCreationDate(Instant.now().getEpochSecond());\n        vault.setCreatorRequestId(creatorRequestId);\n        vault.setNumberOfRecoveryPoints(0);\n        vault.setTags(tags);\n        vaultStore.put(key, vault);\n        LOG.infov(\"Created backup vault {0} in {1}\", vaultName, region);\n        return vault;\n    }\n\n    public BackupVault describeBackupVault(String vaultName, String region) {\n        return vaultStore.get(vaultKey(region, vaultName))\n                .orElseThrow(() -> new AwsException(\"ResourceNotFoundException\", \"Backup vault not found: \" + vaultName, 404));\n    }\n\n    public void deleteBackupVault(String vaultName, String region) {\n        BackupVault vault = describeBackupVault(vaultName, region);\n        if (vault.getNumberOfRecoveryPoints() > 0) {\n            throw new AwsException(\"InvalidRequestException\",\n                    \"Non-empty backup vault cannot be deleted: \" + vaultName, 400);\n        }\n        vaultStore.delete(vaultKey(region, vaultName));\n    }\n\n    public List<BackupVault> listBackupVaults(String region) {\n        String prefix = region + \":\";\n        return vaultStore.scan(k -> k.startsWith(prefix));\n    }\n\n    // ── Plan ───────────────────────────────────────────────────────────────────\n\n    public BackupPlan createBackupPlan(String planName, List<BackupRule> rules,\n                                       String creatorRequestId, String region) {\n        String planId = UUID.randomUUID().toString();\n        BackupPlan plan = new BackupPlan();\n        plan.setBackupPlanId(planId);\n        plan.setBackupPlanArn(regionResolver.buildArn(\"backup\", region, \"backup-plan:\" + planId));","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/backup/BackupService.java#L76-L112","documentation":"Thrown by deleteBackupVault when the vault still contains recovery points (NumberOfRecoveryPoints > 0). AWS Backup requires a vault to be empty before deletion so recovery points are not silently destroyed; Floci enforces the same rule with InvalidRequestException (HTTP 400).","triggerScenarios":"Calling DeleteBackupVault on a vault whose recovery-point count is above zero — i.e. backups have been written into it and not deleted.","commonSituations":"Teardown scripts deleting vaults before their backup plans/jobs; forgetting that continuous or scheduled backups keep adding recovery points; test cleanup leaving the default vault populated.","solutions":["Delete the vault's recovery points first (ListRecoveryPointsByBackupVault + DeleteRecoveryPoint for each), then delete the vault","Ensure backup plans selecting resources into this vault are deleted or disabled so no new points appear","Only then call DeleteBackupVault"],"exampleFix":"null","handlingStrategy":"validation","validationCode":"BackupVault v = backup.describeBackupVault(DescribeBackupVaultRequest.builder()\n    .backupVaultName(vaultName).build());\nif (v.numberOfRecoveryPoints() > 0) { /* empty the vault first */ }","typeGuard":null,"tryCatchPattern":"catch (InvalidRequestException e) { delete recovery points, then retry delete vault; }","preventionTips":["Order teardown: selections, plans, recovery points, then vaults","Disable backup plans before deleting their vault to stop new recovery points"],"tags":["backup","vault","delete","resource-in-use","aws-emulator"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}