floci-io/floci · error · AwsException

ValidationError

ValidationError

Error message

StackSetName must not be empty

What it means

ValidationError from StackSetService.createStackSet when the StackSetName parameter is null or blank. Floci mirrors AWS's requirement that CreateStackSet always carries a non-empty name.

Source

Thrown at src/main/java/io/github/hectorvent/floci/services/cloudformation/StackSetService.java:61

    private final StorageBackend<String, StackSetOperation> operations;

    @Inject
    public StackSetService(CloudFormationService cfnService, StorageFactory storageFactory) {
        this.cfnService = cfnService;
        this.stackSets = storageFactory.create("cloudformation", "cloudformation-stacksets.json",
                new TypeReference<Map<String, StackSet>>() {});
        this.instances = storageFactory.create("cloudformation", "cloudformation-stackset-instances.json",
                new TypeReference<Map<String, StackInstance>>() {});
        this.operations = storageFactory.create("cloudformation", "cloudformation-stackset-operations.json",
                new TypeReference<Map<String, StackSetOperation>>() {});
    }

    // ── StackSet lifecycle ─────────────────────────────────────────────────────

    public StackSet createStackSet(String name, String templateBody, Map<String, String> parameters,
                                   List<String> capabilities, Map<String, String> tags, String description) {
        if (name == null || name.isBlank()) {
            throw new AwsException("ValidationError", "StackSetName must not be empty", 400);
        }
        if (stackSets.get(name).isPresent()) {
            throw new AwsException("NameAlreadyExistsException",
                    "StackSet already exists: " + name, 409);
        }
        // AWS rejects CreateStackSet with no template; the handler resolves TemplateBody/TemplateURL
        // to null when neither is supplied. Without this guard a later CreateStackInstances would
        // deploy empty ("{}") stacks into every target account.
        if (templateBody == null || templateBody.isBlank()) {
            throw new AwsException("ValidationError",
                    "Either TemplateBody or TemplateURL must be specified", 400);
        }
        StackSet ss = new StackSet();
        ss.setStackSetName(name);
        ss.setStackSetId(name + ":" + UUID.randomUUID());
        ss.setTemplateBody(templateBody);
        ss.setDescription(description);
        if (parameters != null) {

View on GitHub (pinned to 62ff490619)

Solutions

  1. Set an explicit, non-blank StackSetName on the CreateStackSet request before sending.
  2. Trace where the name value originates (env var, config file) and validate it is populated at startup rather than at call time.
  3. Note the field is StackSetName (not StackName) on CreateStackSet — using the wrong field leaves it null.

Example fix

// before
cfn.createStackSet(req -> req.stackSetName(stackName)); // stackName may be null

// after
if (stackName == null || stackName.isBlank()) throw new IllegalArgumentException("stackName required");
cfn.createStackSet(req -> req.stackSetName(stackName));
Defensive patterns

Strategy: validation

Validate before calling

if (stackSetName == null || stackSetName.isBlank()) {
    throw new IllegalArgumentException("StackSetName is required");
}
cfn.createStackSet(req -> req.stackSetName(stackSetName)...);

Try / catch

catch CloudFormationException code ValidationError message "StackSetName must not be empty" — this is always a caller bug; fix the request construction rather than retrying.

Prevention

When it happens

Trigger: CreateStackSet called via SDK/CLI with StackName omitted or set to an empty/whitespace string — typically a client bug where the field was never populated.

Common situations: Code building the request from a variable that is null (env var not set, upstream config missing), or a serialization issue that drops the StackSetName field from the Query/JSON request.

Understand the failure class

Background: ValidationError explained: why open-source libraries reject your input — file uploads, YAML manifests, unique fields, and query permissions — this error's family across 13 libraries.

Related errors


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