1

My problem is pretty simple, really.

I wrote a Scala handler class that returns a String containing the following JSON:

{
   "isBase64Encoded":false,
   "statusCode":404,
   "headers":{
      "Content-Type":"text/html"
   },
   "body":"<p>The requested resource could not be found.</p>"
}

My class has the following signature:

object Handler extends RequestHandler[APIGatewayProxyRequestEvent, String] {

  override def handleRequest(input: APIGatewayProxyRequestEvent, context: Context): String = ???

}

I am using the RequestHandler and APIGatewayProxyRequestEvent from the AWS Java SDK.

But when calling it I get the error Execution failed due to configuration error: Malformed Lambda proxy response.

Here's the full log:

Execution log for request 99234b33-2419-11e9-8156-d18557467ee6
Tue Jan 29 22:59:57 UTC 2019 : Starting execution for request: 99234b33-2419-11e9-8156-d18557467ee6
Tue Jan 29 22:59:57 UTC 2019 : HTTP Method: GET, Resource Path: /foo
Tue Jan 29 22:59:57 UTC 2019 : Method request path: {proxy=foo}
Tue Jan 29 22:59:57 UTC 2019 : Method request query string: {}
Tue Jan 29 22:59:57 UTC 2019 : Method request headers: {}
Tue Jan 29 22:59:57 UTC 2019 : Method request body before transformations: 
Tue Jan 29 22:59:57 UTC 2019 : Endpoint request URI: https://lambda.eu-central-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-central-1:794147591978:function:xxxx/invocations
Tue Jan 29 22:59:57 UTC 2019 : Endpoint request headers: {x-amzn-lambda-integration-tag=99234b33-2419-11e9-8156-d18557467ee6, Authorization=***************************************************************************************************************************************************************************************************************************************************************************************************************************e4cddd, X-Amz-Date=20190129T225957Z, x-amzn-apigateway-api-id=0lypbq3och, X-Amz-Source-Arn=arn:aws:execute-api:eu-central-1:794147591978:0lypbq3och/test-invoke-stage/GET/{proxy+}, Accept=application/json, User-Agent=AmazonAPIGateway_0lypbq3och, X-Amz-Security-Token=FQoGZXIvYXdzECAaDNe+xBH2UeEIx4SHoyK9A24kTKoADNrqj2oEsP7wwqlNw/Z3DHCHLqagRvBVke5R7MUg4G4cTFG0KQia0x3x4CqYIjTtQ6oFp2iWuTV8LOuMQz6r4T75Y5wrvl3c2qfkUd7m+Oj2B5Q0TXKtI/DBa0I4ChqAVgamMuPTVbZga0u9gG4d+v7sEzeOrMDrp1AsiBYQMG+S9MbTC/2+UuFe2X7elWnAhSXAZ/LA7w/dQu8+UvPPLN2xVl0W7d/9Nsq0BM1B5OBgJaj5gO9r8zh1Yto96100F3JaIdjLk+btcyy53OnL+SQWaS2isF/2Gl [TRUNCATED]
Tue Jan 29 22:59:57 UTC 2019 : Endpoint request body after transformations: {"resource":"/{proxy+}","path":"/foo","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":{"proxy":"foo"},"stageVariables":null,"requestContext":{"path":"/{proxy+}","accountId":"794147591978","resourceId":"m044wv","stage":"test-invoke-stage","domainPrefix":"testPrefix","requestId":"99234b33-2419-11e9-8156-d18557467ee6","identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","cognitoAuthenticationType":null,"userArn":"arn:aws:iam::794147591978:root","apiKeyId":"test-invoke-api-key-id","userAgent":"aws-internal/3 aws-sdk-java/1.11.481 Linux/4.9.137-0.1.ac.218.74.329.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.192-b12 java/1.8.0_192","accountId":"794147591978","caller":"794147591978","sourceIp":"test-invoke-source-ip","accessKey":"ASIA3RZXCS4VNQOJVZON","cognitoAuthenticationProvider":null,"user":"794147591978"},"domainName":"testPrefix.tes [TRUNCATED]
Tue Jan 29 22:59:57 UTC 2019 : Sending request to https://lambda.eu-central-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-central-1:794147591978:function:xxx/invocations
Tue Jan 29 22:59:57 UTC 2019 : Received response. Integration latency: 36 ms
Tue Jan 29 22:59:57 UTC 2019 : Endpoint response body before transformations: "{\"isBase64Encoded\":false,\"statusCode\":404,\"headers\":{\"Content-Type\":\"text/html\"},\"body\":\"<p>The requested resource could not be found.</p>\"}"
Tue Jan 29 22:59:57 UTC 2019 : Endpoint response headers: {Date=Tue, 29 Jan 2019 22:59:57 GMT, Content-Type=application/json, Content-Length=156, Connection=keep-alive, x-amzn-RequestId=bd41f477-92ae-4068-a062-16a149cf7748, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-5c50daed-8291ac2e0f2b8a251dbf1865;sampled=0}
Tue Jan 29 22:59:57 UTC 2019 : Execution failed due to configuration error: Malformed Lambda proxy response
Tue Jan 29 22:59:57 UTC 2019 : Method completed with status: 502

The JSON included in the logs seems (apart from the escaping) to match exactly what I would expect and it matches the documentation at the documentation, as well.

So why am I getting this error?

1 Answer 1

1

Try JSON.stringify() on the body value:

{
   "isBase64Encoded":false,
   "statusCode":404,
   "headers":{
      "Content-Type":"text/html"
   },
   "body":JSON.stringify("<p>The requested resource could not be found.</p>")
}

I know it seems silly but there is a difference in output:

console.log("<p>The requested resource could not be found.</p>");
// "<p>The requested resource could not be found.</p>"

console.log(JSON.stringify("<p>The requested resource could not be found.</p>"));
// "'<p>The requested resource could not be found.</p>'"
Sign up to request clarification or add additional context in comments.

3 Comments

As you may notice the output is already a valid JSON. Apart from that JSON.stringify is JavaScript, and I am using JVM. I will update my question with some more context.
Ah that makes sense, I apologize. Thank you for the additional context. I still believe the problem is the string representation of the JSON object in your response. "{\"isBase64Encoded\":false,\"statusCode\":404,\"headers\":{\"Content-Type\":\"text/html\"},\"body\":\"<p>The requested resource could not be found.</p>\"}" is valid JSON in the same way "foo" is valid JSON. It is passed straight from the server without being parsed as an object. Look at the difference between the request body and response body in the logs.
The problem is that I confirmed that the additional escaping happens somewhere after my Lambda execution...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.