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.

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)

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.