floci-io/floci · error · AwsException
BadRequestException
BadRequestException
Error message
e.getMessage()
What it means
PutMethodResponse in the API Gateway emulator parses the raw request body with Jackson; any IOException from objectMapper.readValue is rethrown as a 400 BadRequestException carrying Jackson's message. Malformed JSON, a non-object payload (array/string), or unreadable content all land here.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/apigateway/ApiGatewayController.java:105
return Response.ok(toMethodResponseNode(service.getMethodResponse(region, apiId, resourceId, httpMethod, statusCode)).toString()).type(MediaType.APPLICATION_JSON).build();
}
@PUT
@Path("/restapis/{apiId}/resources/{resourceId}/methods/{httpMethod}/responses/{statusCode}")
public Response putMethodResponse(@Context HttpHeaders headers,
@PathParam("apiId") String apiId,
@PathParam("resourceId") String resourceId,
@PathParam("httpMethod") String httpMethod,
@PathParam("statusCode") String statusCode,
String body) {
String region = regionResolver.resolveRegion(headers);
try {
@SuppressWarnings("unchecked")
Map<String, Object> request = objectMapper.readValue(body, Map.class);
MethodResponse resp = service.putMethodResponse(region, apiId, resourceId, httpMethod, statusCode, request);
return Response.status(201).entity(toMethodResponseNode(resp).toString()).type(MediaType.APPLICATION_JSON).build();
} catch (IOException e) {
throw new AwsException("BadRequestException", e.getMessage(), 400);
}
}
@GET
@Path("/restapis/{apiId}/resources/{resourceId}/methods/{httpMethod}/integration/responses/{statusCode}")
public Response getIntegrationResponse(@Context HttpHeaders headers,
@PathParam("apiId") String apiId,
@PathParam("resourceId") String resourceId,
@PathParam("httpMethod") String httpMethod,
@PathParam("statusCode") String statusCode) {
String region = regionResolver.resolveRegion(headers);
return Response.ok(toIntegrationResponseNode(service.getIntegrationResponse(region, apiId, resourceId, httpMethod, statusCode)).toString()).type(MediaType.APPLICATION_JSON).build();
}
@PUT
@Path("/restapis/{apiId}/resources/{resourceId}/methods/{httpMethod}/integration/responses/{statusCode}")
public Response putIntegrationResponse(@Context HttpHeaders headers,
@PathParam("apiId") String apiId,View on GitHub (pinned to 62ff490619)
Solutions
- Validate the body is a JSON object before sending (jq . <<< body or a client-side parse)
- Send exactly the expected shape: {"selectionPattern": "...", "responseTemplates": {...}}
Example fix
// before
String body = "[\"selectionPattern\"]"; // JSON array
// after
String body = "{\"selectionPattern\": \"2\\d{2}\"}"; Defensive patterns
Strategy: validation
Validate before calling
ObjectMapper om = new ObjectMapper();
JsonNode n = om.readTree(body);
if (!n.isObject()) throw new IllegalArgumentException("Body must be a JSON object"); Type guard
boolean isValidMethodResponseBody(String body, ObjectMapper om) throws Exception {
JsonNode n = om.readTree(body);
return n.isObject();
} Try / catch
try {
apigw.putMethodResponse(req);
} catch (BadRequestException e) {
// Jackson message indicates the exact offset; re-check the serialized body
log.error("Rejected body: {}", rawBody);
throw e;
} Prevention
- Always set Content-Type: application/json on REST calls to the emulator
- Prefer the AWS SDK over hand-rolled HTTP for management-plane calls
When it happens
Trigger: PUT /restapis/{apiId}/resources/{resourceId}/methods/{httpMethod}/responses/{statusCode} with a body that is not a valid JSON object — trailing commas, single quotes, empty string, or a JSON array.
Common situations: Hand-rolled curl requests with shell-quoting mistakes; SDK clients that send an empty entity on error paths; proxies or transforms that mangle the JSON body in transit.
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
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/a70fba7d2e451b9f.
Report an issue: GitHub.