{"record":{"id":"266e6ee178fe9b70","repo":"floci-io/floci","slug":"invalidargument-266e6e","errorCode":"InvalidArgument","errorMessage":"The alias must not be empty.","messagePattern":"The alias must not be empty\\.","errorType":"error_code","errorClass":"AwsException","httpStatus":400,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontService.java","lineNumber":205,"sourceCode":"        if (marker != null && !marker.isEmpty()) {\n            int idx = 0;\n            for (int i = 0; i < all.size(); i++) {\n                if (all.get(i).getId().equals(marker)) {\n                    idx = i + 1;\n                    break;\n                }\n            }\n            all = all.subList(idx, all.size());\n        }\n        if (maxItems > 0 && all.size() > maxItems) {\n            return all.subList(0, maxItems);\n        }\n        return all;\n    }\n\n    public synchronized void associateAlias(String targetDistributionId, String alias) {\n        if (alias == null || alias.isBlank()) {\n            throw new AwsException(\"InvalidArgument\", \"The alias must not be empty.\", 400);\n        }\n        Distribution dist = getDistribution(targetDistributionId);\n        if (dist.getConfig() == null) {\n            throw new AwsException(\"InvalidArgument\", \"The target distribution has no configuration.\", 400);\n        }\n        for (Distribution candidate : distStore.scan(k -> true)) {\n            if (targetDistributionId.equals(candidate.getId()) || candidate.getConfig() == null\n                    || candidate.getConfig().getAliases() == null) {\n                continue;\n            }\n            List<String> previousAliases = candidate.getConfig().getAliases();\n            List<String> remaining = new ArrayList<>(previousAliases);\n            remaining.removeIf(existing -> alias.equalsIgnoreCase(existing));\n            if (remaining.size() != previousAliases.size()) {\n                candidate.getConfig().setAliases(remaining);\n                candidate.setEtag(UUID.randomUUID().toString());\n                candidate.setLastModifiedTime(Instant.now());\n                distStore.put(candidate.getId(), candidate);","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontService.java#L187-L223","documentation":"Thrown by Floci's CloudFront emulator when AssociateAlias is called with an alias that is null, empty, or whitespace-only. The service validates the alias string before touching distribution state, mirroring AWS CloudFront's InvalidArgument (HTTP 400) for a missing CNAME. It fails fast: no alias bookkeeping is modified when this fires.","triggerScenarios":"Calling associateAlias(targetDistributionId, alias) on CloudFrontService where alias == null, alias.isEmpty(), or alias is only whitespace. Via the wire this maps to an AssociateAlias request whose CNAME field was omitted or sent blank.","commonSituations":"Building the alias from an environment variable or config key that is unset in one environment; a templating layer that renders an empty string; passing the wrong variable (e.g. the distribution ID) into the alias parameter.","solutions":["Check the alias is non-null and non-blank before calling associateAlias (e.g. Objects.requireNonNull + isBlank guard).","Trace where the alias value originates (env var, config, CLI arg) and fix the unset/blank source.","If the value arrives from user input, validate and reject it at your API boundary with a clear message instead of relying on the 400."],"exampleFix":"// before\ncloudFrontService.associateAlias(distId, System.getenv(\"CF_ALIAS\")); // may be null\n\n// after\nString alias = System.getenv(\"CF_ALIAS\");\nif (alias == null || alias.isBlank()) {\n    throw new IllegalArgumentException(\"CF_ALIAS must be set to a CNAME like www.example.com\");\n}\ncloudFrontService.associateAlias(distId, alias);","handlingStrategy":"validation","validationCode":"boolean isAssociateableAlias(String alias) {\n    return alias != null && !alias.isBlank() && alias.matches(\"(\\\\w[-_\\\\w]*\\\\.)+[a-zA-Z]{2,}\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate alias non-blank and domain-shaped at the input boundary before calling AssociateAlias.","Fail fast on unset env/config values that feed the alias instead of letting them flow into the API call.","Write one integration test asserting blank aliases are rejected client-side."],"tags":["cloudfront","aws","validation","cname","alias"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}