floci-io/floci · error · AppSyncTransportException
BadRequestException
BadRequestException
Error message
Missing operation name.
What it means
A GraphQL execution request contained more than one operation definition (multiple anonymous or named operations) but no operationName was supplied, so the executor cannot know which one to run. Floci's QueryExecutor raises HTTP 400 BadRequestException 'Missing operation name.', matching AppSync's behavior for ambiguous documents.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/appsync/graphql/QueryExecutor.java:40
public class QueryExecutor {
private final AppSyncErrorFormatter formatter;
@Inject
public QueryExecutor(AppSyncErrorFormatter formatter) {
this.formatter = formatter;
}
public Map<String, Object> execute(GraphQLSchema schema, String query,
Map<String, Object> variables, String operationName) {
return execute(SchemaRegistry.buildGraphQL(schema), query, variables, operationName);
}
public Map<String, Object> execute(GraphQL graphQL, String query,
Map<String, Object> variables, String operationName) {
List<OperationDefinition> operations = parseOperations(query);
if (operations.size() > 1 && (operationName == null || operationName.isBlank())) {
throw new AppSyncTransportException(400, "BadRequestException",
AppSyncErrorFormatter.MSG_MISSING_OPERATION_NAME);
}
OperationDefinition selected = selectOperation(operations, operationName);
if (selected != null && selected.getOperation() == OperationDefinition.Operation.SUBSCRIPTION) {
ExecutionResult rejected = ExecutionResultImpl.newExecutionResult()
.addError(GraphqlErrorBuilder.newError()
.message("Subscriptions are not supported over HTTP")
.errorType(ErrorType.OperationNotSupported)
.build())
.build();
return formatter.format(rejected);
}
ExecutionInput.Builder inputBuilder = ExecutionInput.newExecutionInput().query(query);
if (variables != null) {
inputBuilder.variables(variables);
}View on GitHub (pinned to 62ff490619)
Solutions
- Add "operationName": "NameOfOperation" matching one top-level operation in the document.
- Or split the document so the request contains exactly one operation.
- If a library builds the request for you, set its operation-name option (e.g. graphql-request/mutation function name).
Example fix
// before
fetch(url, { body: JSON.stringify({ query: 'query A { a } query B { b }' }) });
// after
fetch(url, { body: JSON.stringify({ query: 'query A { a } query B { b }', operationName: 'A' }) }); Defensive patterns
Strategy: validation
Validate before calling
const ops = [...query.matchAll(/\b(query|mutation|subscription)\s+([A-Za-z]\w*)/g)].map(m => m[2]);
const anon = /^\s*(query|mutation|subscription)?\s*[({]/m.test(query);
if (ops.length + (anon ? 1 : 0) > 1 && !operationName) throw new Error('operationName required'); Try / catch
catch (BadRequestException e) {
if ("Missing operation name.".equals(e.getMessage())) { /* set operationName to the intended op and retry */ }
} Prevention
- One operation per request document; pass operationName whenever the document has more than one.
- Let GraphQL client libraries manage operation selection.
- Add a preflight check counting top-level operations in shared query documents.
When it happens
Trigger: POSTing a document like 'query A { ... } query B { ... }' or 'query { ... } mutation { ... }' with no operationName field; also an anonymous query plus a named mutation in one document. Conversely, a single-operation document needs no operationName.
Common situations: Concatenating query fragments for convenience; shipping whole schema test documents; code that composes queries from multiple templates without selecting one.
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
- Invalid JSON: {}
- Invalid AWSDateTime: {}
- Invalid AWSDate: {}
- Invalid AWSTime: {}
- AWSTimestamp out of range: {}
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/bb7c631540e284ee.
Report an issue: GitHub.