floci-io/floci · error · AwsException

ResourceNotFoundException

ResourceNotFoundException

Error message

Backup selection not found in plan: {planId}

What it means

Thrown by getBackupSelection when the selection exists in the store but belongs to a different plan than the one in the request. AWS Backup scopes selections under their plan ARN, so a plan/selection mismatch is reported as ResourceNotFoundException (HTTP 404) — the pair simply does not exist together.

Solutions

  1. Use ListBackupSelections on the plan to get IDs guaranteed to match, then retry with that plan/selection pair
  2. Verify both identifiers came from the same creation flow — regenerate them if unsure
Defensive patterns

Strategy: validation

Validate before calling

boolean pairExists = backup.listBackupSelections(ListBackupSelectionsRequest.builder()
    .backupPlanId(planId).build()).backupSelectionsList().stream()
    .anyMatch(s -> selectionId.equals(s.selectionId()));
if (!pairExists) throw new NoSuchResourceException(planId + "/" + selectionId);

Try / catch

catch (ResourceNotFoundException e) { re-enumerate selections under the plan and correct the stale id; }

Prevention

When it happens

Trigger: Calling GetBackupSelection (or DeleteBackupSelection, which delegates to it) with a selectionId that exists but whose BackupPlanId differs from the requested planId.

Common situations: Copy-pasting IDs between test fixtures so selection and plan ids cross wires; enumerating all selections globally and calling them against the wrong plan; truncation or typo in one of the two identifiers.

Related errors


AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14). Data as JSON: /api/errors/f47a54cbdddd0000. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/github/hectorvent/floci/services/backup/BackupService.java:179

        String selectionId = UUID.randomUUID().toString();
        BackupSelection selection = new BackupSelection();
        selection.setSelectionId(selectionId);
        selection.setSelectionName(selectionName);
        selection.setBackupPlanId(planId);
        selection.setIamRoleArn(iamRoleArn);
        selection.setResources(resources);
        selection.setNotResources(notResources);
        selection.setCreationDate(Instant.now().getEpochSecond());
        selection.setCreatorRequestId(creatorRequestId);
        selectionStore.put(selectionId, selection);
        return selection;
    }

    public BackupSelection getBackupSelection(String planId, String selectionId) {
        BackupSelection sel = selectionStore.get(selectionId)
                .orElseThrow(() -> new AwsException("ResourceNotFoundException", "Backup selection not found: " + selectionId, 404));
        if (!planId.equals(sel.getBackupPlanId())) {
            throw new AwsException("ResourceNotFoundException", "Backup selection not found in plan: " + planId, 404);
        }
        return sel;
    }

    public void deleteBackupSelection(String planId, String selectionId) {
        getBackupSelection(planId, selectionId);
        selectionStore.delete(selectionId);
    }

    public List<BackupSelection> listBackupSelections(String planId) {
        return selectionStore.scan(k -> true).stream()
                .filter(s -> planId.equals(s.getBackupPlanId()))
                .toList();
    }

    // ── Job ────────────────────────────────────────────────────────────────────

    public BackupJob startBackupJob(String vaultName, String resourceArn, String iamRoleArn,

View on GitHub (pinned to 62ff490619)