floci-io/floci · error · AwsException

ValidationException

ValidationException

Error message

An export with the name {name} already exists.

What it means

Thrown by Floci's BCM Data Exports emulator from CreateExport when an export with the same Name already exists (names are unique per account, matching real AWS). createExport calls findByName over the export store before persisting and returns ValidationException (400) on collision.

Source

Thrown at src/main/java/io/github/hectorvent/floci/services/bcmdataexports/BcmDataExportsService.java:85

                        new TypeReference<Map<String, ExportExecution>>() {}),
                regionResolver);
    }

    BcmDataExportsService(StorageBackend<String, Export> exportStore,
                          StorageBackend<String, ExportExecution> executionStore,
                          RegionResolver regionResolver) {
        this.exportStore = exportStore;
        this.executionStore = executionStore;
        this.regionResolver = regionResolver;
    }

    /** {@code CreateExport} — creates and persists a new {@link Export}. */
    public Export createExport(Export incoming, Map<String, String> resourceTags, String region) {
        validateExport(incoming);
        String accountId = regionResolver.getAccountId();

        if (findByName(incoming.getName()) != null) {
            throw new AwsException("ValidationException",
                    "An export with the name " + incoming.getName() + " already exists.", 400);
        }

        String exportArn = buildArn(region, accountId, incoming.getName());
        long now = System.currentTimeMillis();
        incoming.setExportArn(exportArn);
        incoming.setCreatedAt(now);
        incoming.setLastUpdatedAt(now);
        incoming.setExportStatus("HEALTHY");
        incoming.setOwnerAccountId(accountId);
        if (resourceTags != null) {
            incoming.setResourceTags(new HashMap<>(resourceTags));
        }

        exportStore.put(exportKey(exportArn), incoming);
        LOG.infov("Created BCM export: {0} (arn={1})", incoming.getName(), exportArn);
        return incoming;
    }

View on GitHub (pinned to 62ff490619)

Solutions

  1. Call DeleteExport on the existing export before recreating it, or pick a unique name (add a run id/UUID suffix).
  2. Check for the existing export first with GetExport/ListExports and reuse it when appropriate.
  3. Make test teardown delete exports so re-runs start clean.
  4. For retries, treat this error as 'already created' rather than failure.

Example fix

// before
bcm.createExport(r -> r.name("daily-cost").dataQuery(dq).refreshCadence(rc));

// after
try {
    bcm.createExport(r -> r.name("daily-cost").dataQuery(dq).refreshCadence(rc));
} catch (ValidationException alreadyExists) {
    bcm.deleteExport(r -> r.exportArn(existingArn));
    bcm.createExport(r -> r.name("daily-cost").dataQuery(dq).refreshCadence(rc));
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists = bcm.listExports().exports().stream()
    .anyMatch(e -> e.name().equals(name));

Try / catch

try {
    bcm.createExport(req);
} catch (software.amazon.awssdk.services.bcmdataexports.model.ValidationException e) {
    if (e.getMessage().contains("already exists")) {
        // reuse or delete-then-recreate
    } else { throw e; }
}

Prevention

When it happens

Trigger: bcmDataExportsClient.createExport(r -> r.name("my-export")...) twice without deleting the first export; test fixtures re-running CreateExport with fixed names against persistent storage.

Common situations: Integration tests with hardcoded export names against Floci in persistent/hybrid storage mode; CI re-runs without cleanup; retry logic that re-sends CreateExport after a timeout even though the first call succeeded.

Related errors


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