floci-io/floci · error · AwsException
BadRequestException
BadRequestException
Error message
A GraphQL API name is required
What it means
Thrown by AppSyncService.createGraphqlApi when the request body has no 'name' field or a blank one. AWS requires a name for every GraphQL API; Floci rejects the create with BadRequestException (HTTP 400) before generating an API id. Note it fires after assertNoSchemaBusyAnywhere, so an in-flight schema creation fails earlier with ConcurrentModificationException.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/appsync/AppSyncService.java:76
this.typeStore = storageFactory.create("appsync", "appsync-types.json", new TypeReference<>() {});
this.domainStore = storageFactory.create("appsync", "appsync-domainnames.json", new TypeReference<>() {});
this.associationStore = storageFactory.create("appsync", "appsync-associations.json", new TypeReference<>() {});
this.channelNamespaceStore = storageFactory.create("appsync", "appsync-channelnamespaces.json", new TypeReference<>() {});
this.mergedApiAssociationStore = storageFactory.create("appsync", "appsync-merged-api-associations.json", new TypeReference<>() {});
this.regionResolver = regionResolver;
this.schemaRegistry = schemaRegistry;
this.schemaCreationWorker = schemaCreationWorker;
this.requestContextInstance = requestContextInstance;
this.objectMapper = objectMapper;
}
// ──────────────────────────── GraphQL API ────────────────────────────
public GraphqlApi createGraphqlApi(Map<String, Object> request, String region) {
assertNoSchemaBusyAnywhere();
String name = (String) request.get("name");
if (name == null || name.isBlank()) {
throw new AwsException("BadRequestException", "A GraphQL API name is required", 400);
}
String authType = (String) request.get("authenticationType");
if (authType == null || authType.isBlank()) {
throw new AwsException("BadRequestException", "The authenticationType is required", 400);
}
String apiId = generateApiId();
GraphqlApi api = new GraphqlApi();
api.setApiId(apiId);
api.setName(name);
api.setAuthenticationType(parseEnum(AuthenticationType.class, authType));
Object xrayValue = request.get("xrayEnabled");
if (xrayValue instanceof Boolean b) {
api.setXrayEnabled(b);
} else if (xrayValue instanceof String s) {
api.setXrayEnabled(Boolean.parseBoolean(s));
} else {
api.setXrayEnabled(false);
}View on GitHub (pinned to 62ff490619)
Solutions
- Include a non-empty 'name' string in the CreateGraphqlApi request body.
- If using the AWS SDK, the builder enforces this client-side in newer versions — keep it enabled rather than bypassing validation.
- Validate request payloads against the AppSync CreateGraphqlApi schema before forwarding.
Example fix
// before
appSync.createGraphqlApi(b -> b.authenticationType(AuthenticationType.API_KEY)); // no name
// after
appSync.createGraphqlApi(b -> b.name("MyApi")
.authenticationType(AuthenticationType.API_KEY)); Defensive patterns
Strategy: validation
Validate before calling
if (request.get("name") == null || ((String) request.get("name")).isBlank()) {
throw new IllegalArgumentException("GraphqlApi 'name' is required");
}
appSyncClient.createGraphqlApi(request); Type guard
boolean isCreateApiRequestValid(Map<String, Object> req) {
return req.get("name") instanceof String s && !s.isBlank();
} Try / catch
try {
appSync.createGraphqlApi(req);
} catch (BadRequestException e) {
if (e.getMessage().contains("name is required")) {
// populate name and retry
}
throw e;
} Prevention
- Validate AppSync request maps at the edge before forwarding to the SDK.
- Keep template files for CreateGraphqlApi with both name and authenticationType pre-filled.
When it happens
Trigger: POST /v1/apis with a JSON body lacking 'name' (e.g. only authenticationType set); name key spelled 'Name' or 'apiName'; empty string name.
Common situations: Raw REST calls or Terraform/CDK templates with a missing name attribute; SDK builders where name is set conditionally; thin wrappers forwarding a partially populated map.
Understand the failure class
Background: BadRequestException (HTTP 400) — NestJS 'Bad Request' Errors: Why They Fire and How to Fix Them — this error's family across 4 libraries.
Related errors
- InvalidNextTokenException
- ValidationException
- IdempotencyException
- BadRequestException
- ApiKeyLimitExceededException
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/555a8f1025ae4951.
Report an issue: GitHub.