floci-io/floci · error · AwsException
BadRequestException
BadRequestException
Error message
Invalid resource ARN: ${arn} What it means
Thrown by CodeDeploy's BatchGetDeployments when any requested id is missing from the region's deployment store; the stream throws on the first null lookup. As with batchGetApplications, this is stricter than real AWS, where BatchGetDeployments omits unknown ids from the response.
Source
Thrown at src/main/java/io/github/hectorvent/floci/core/common/SharedTagsController.java:249
}
return (values == null) ? List.of() : List.copyOf(values);
}
private String readResourceArn(String body) {
try {
JsonNode node = objectMapper.readTree((body == null || body.isBlank()) ? "{}" : body);
return node.path("resourceArn").asText(null);
} catch (Exception e) {
throw new AwsException("BadRequestException", e.getMessage(), 400);
}
}
private TagHandler resolveHandler(String arn) {
String serviceKey;
try {
serviceKey = AwsArnUtils.parse(arn).service();
} catch (IllegalArgumentException e) {
throw new AwsException("BadRequestException",
"Invalid resource ARN: " + arn, 400);
}
TagHandler handler = handlersByServiceKey.get(serviceKey);
if (handler == null) {
// Surface an unregistered service as an invalid-ARN error so floci's
// internal routing isn't leaked to the client.
throw new AwsException("BadRequestException",
"Invalid resource ARN: " + arn, 400);
}
return handler;
}
}
View on GitHub (pinned to 62ff490619)
Solutions
- Filter requested ids against ListDeployments output before batching.
- Drop persisted ids older than the current emulator session when storage is memory-based.
- Fall back to per-id GetDeployment with a try-catch if you must tolerate missing ids.
Example fix
// before
BatchGetDeploymentsResponse resp = codedeploy.batchGetDeployments(
r -> r.deploymentIds(List.of("d-1", "d-gone", "d-3")));
// after
Set<String> live = new HashSet<>(codedeploy.listDeployments().deployments());
List<String> wanted = List.of("d-1", "d-gone", "d-3").stream().filter(live::contains).toList();
BatchGetDeploymentsResponse resp = codedeploy.batchGetDeployments(r -> r.deploymentIds(wanted)); Defensive patterns
Strategy: validation
Validate before calling
Set<String> live = new HashSet<>(codedeploy.listDeployments().deployments()); List<String> safe = deploymentIds.stream().filter(live::contains).toList();
Try / catch
try {
codedeploy.batchGetDeployments(r -> r.deploymentIds(ids));
} catch (DeploymentDoesNotExistException e) {
// one id is stale — filter against ListDeployments and retry
} Prevention
- Pre-filter batch id lists against ListDeployments — Floci fails the whole batch on one bad id.
- Drop ids older than the current emulator session.
- Degrade to per-id GetDeployment with try-catch when partial results are acceptable.
When it happens
Trigger: BatchGetDeployments with a list containing at least one stale, deleted, cross-region, or malformed deployment id; bulk status pollers feeding unfiltered ids into one batch call.
Common situations: Code ported from real AWS expecting lenient batch semantics; mixing deployment ids collected before an emulator restart with fresh ones.
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/fd5d89bcc95f0122.
Report an issue: GitHub.