Event body can not be parsed on AWS API Gateway

I have this simple function I am trying to implement as a test for getting started with serverless.

function addNumbers(numbers: Array<number>) {
  console.log("CloudWatch: numbers: \n", numbers)
  const reducer = (accumulator: number, currentValue: number) => accumulator + currentValue
  return numbers.reduce(reducer)
}

This all works perfectly fine when I test the function locally and when I invoke the function locally via:

serverless invoke local --function add --path "./sampleData/data.json"

Here is that sample data:

{
  "body": {
      "numbers": [1,2,3]
  }
}

Please note that this file was created using the tab key for indentation.

When the function is invoked locally this is the expected result:

{
  "statusCode": 200,
  "body": "6"
}

Which we do get when run locally.

Now, it is a known “issue” that when using API Gateway, apparently the event body is stringified for some reason. This is noted elsewhere on this forum and in this stackoverflow amazon web services - Getting json body in aws Lambda via API gateway - Stack Overflow

So here is the handler function with excessive console logging to attempt to point out the difference:

You can see, what I am doing in an attempt to make the two environments the same so I can properly test, is to stringify the body myself first so that it should be in the same state on each platform.

Then we take the known string and parse it. The problem is on AWS, this is still returning a string. and I believe this is because there may be invisible characters “/r/t” in the string on AWS which is not allowing the parse action.

Here is the local output:

Stringified Body: 
{"numbers":[1,2,3]}
TypeOf ParsedBody: 
object
Parsed Body: 
{ numbers: [ 1, 2, 3 ] }
CloudWatch: numbers: 
[ 1, 2, 3 ]

And here is what Cloudwatch is showing:

Slightly confusing on my part sorry, I incorrectly labeled one of the console logs. The second “parsed body” as you can see in the source above is attempting to output “userNumbers” which you can see has a type of undefined.

It is undefined because we can see that “Parsed Body” is for some reason of type “string” when if we ran it locally, we can see that it should be of type “Object”.

This has something to do with the formatting of the string I believe or might there be another reason for this?

Edit:

So I have gone a step further in testing and removed the array I was expecting, thinking perhaps it was somehow a bug involving the array.

I am not expecting a JSON object with two keys “numA” and “numB”.

Here is the CURL POST request I made:

curl -XPOST -d '{"numA": 987,"numB": 789}' 'https://<blah>.execute-api.us-west-2.amazonaws.com/dev/add/'

In the logs on cloud watch I can see the event body has these additional invisible characters:

"body": "{\n\t\"numA\": 44,\n\t\"numB\": 123\n}"

This I believe is causing JSON.parse to fail