floci-io/floci · error · AwsException
InternalError
InternalError
Error message
e.getMessage() != null ? e.getMessage() : "Service invocation failed"
What it means
InternalError (HTTP 500) is the catch-all rethrown by ApiGatewayService's AWS integration router when a routed service handler throws anything that is not itself an AwsException. The original exception's message is preserved when present ('e.getMessage()' is non-null), otherwise the generic text 'Service invocation failed' is used. It signals a defect or unexpected condition inside the emulator's service dispatch, not a malformed client request.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/apigateway/AwsServiceRouter.java:175
case "dynamodb" -> dynamoDbHandler.handle(action, requestBody, region);
case "sqs" -> sqsHandler.handle(action, requestBody, region);
case "sns" -> snsHandler.handle(action, requestBody, region);
case "events" -> eventBridgeHandler.handle(action, requestBody, region);
case "ssm" -> ssmHandler.handle(action, requestBody, region);
case "kinesis" -> kinesisHandler.handle(action, requestBody, region);
case "logs" -> logsHandler.handle(action, requestBody, region);
case "monitoring" -> metricsHandler.handle(action, requestBody, region);
case "secretsmanager" -> secretsManagerHandler.handle(action, requestBody, region);
case "kms" -> kmsHandler.handle(action, requestBody, region);
case "cognito-idp" -> cognitoHandler.handle(action, requestBody, region);
case "acm" -> acmHandler.handle(action, requestBody, region);
default -> throw new AwsException("UnknownService",
"Unsupported AWS service integration: " + service, 400);
};
} catch (AwsException e) {
throw e;
} catch (Exception e) {
throw new AwsException("InternalError",
e.getMessage() != null ? e.getMessage() : "Service invocation failed", 500);
}
}
/**
* Dispatches an AWS query-protocol (form-encoded) integration request.
*
* <p>Used for {@code path/}-style integration URIs whose VTL request template renders an
* {@code application/x-www-form-urlencoded} body in the AWS query protocol, e.g.
* {@code Action=SendMessage&QueueUrl=...&MessageBody=...}. The {@code Action} parameter
* selects the operation, mirroring {@link io.github.hectorvent.floci.core.common.AwsQueryController}.
*
* @param service the AWS service name from the URI (e.g., "sqs")
* @param params the parsed form parameters, including {@code Action}
* @param region the AWS region
* @return the service response (query-protocol XML)
*/
public Response invokeQuery(String service, MultivaluedMap<String, String> params, String region) {View on GitHub (pinned to 62ff490619)
Solutions
- Inspect the Floci server logs for the stack trace of the wrapped exception — the InternalError message is just the original exception's getMessage(), which is often the real clue.
- Capture the rendered integration request (enable API Gateway execution logging / test-invoke) and replay the same action directly against the target service to isolate whether the payload is the problem.
- Simplify the VTL template to a minimal known-good body and re-add transformations incrementally until the failure reappears.
- If the payload is valid, report the exception message plus the service/action pair as a Floci bug.
Defensive patterns
Strategy: try-catch
Try / catch
catch (AwsException e) {
if ("InternalError".equals(e.getCode())) {
// emulator-side fault: capture the message (it carries the cause's text) and report,
// never retry blindly — the same template will fail identically
log.error("Integration dispatch failed: {}", e.getMessage());
throw new IntegrationExecutionException("Check Floci logs for the wrapped stack trace", e);
}
throw e;
} Prevention
- Test VTL templates against the target service directly before wiring them into an integration.
- Run Floci with debug logging during integration development so wrapped causes are visible immediately.
- Report reproducible InternalErrors with the service/action pair and template to the Floci tracker.
When it happens
Trigger: An integration request is routed to a supported handler (sqs, sns, dynamodb, ...) and that handler throws a RuntimeException — e.g. a JSON parse error on the VTL-rendered body, a ClassCastException on a response field, or an NPE on a missing parameter the handler did not validate. The switch in invokeJson() succeeds; the failure happens inside handle().
Common situations: VTL request templates that render malformed JSON for the target service action, causing downstream parse exceptions. Emulator edge cases such as a target resource deleted concurrently between route and handle. Version mismatches after upgrading Floci where a handler signature changed.
Related errors
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/b381edb06824f369.
Report an issue: GitHub.