AWS Lambda Error : 'Could not parse request body into json ' when url parameter contains JSON array

12,612

Solution 1

Be sure to add .replaceAll("\\'","'") to your request body passthrough template after .escapeJavaScript(data)

I found this bit from AWS's documentation to be very helpful for this issue:

$util.escapeJavaScript()

Escapes the characters in a string using JavaScript string rules.

Note This function will turn any regular single quotes (') into escaped ones (\'). However, the escaped single quotes are not valid in JSON. Thus, when the output from this function is used in a JSON property, you must turn any escaped single quotes (\') back to regular single quotes ('). This is shown in the following example: $util.escapeJavaScript(data).replaceAll("\\'","'")

Solution 2

I don't have a solution but I have narrowed the root cause. Lambda does not seem to like single quotes to be escaped with a single slash.

If you hardcode your mapping template to look like this:

{
    "query-fixed": {
        "param": "[[\"kurlo jack\\'s book\",\"Adventure Books\",8.8,1]]"
    }
}

my test Lambda invocation succeeds. However, if you hardcode the template to this:

{
    "query-fixed": {
        "param": "[[\"kurlo jack\'s book\",\"Adventure Books\",8.8,1]]"
    }
}

I get the same error message that you got above. Unfortunately, the second variation is what API Gateway produces for the Lambda invocation.

A workaround might involve using the template to replace single quotes escaped with slash to two slashes. See Replace a Substring of a String in Velocity Template Language

I'll follow up with Lambda internally and update if I hear anything or have a functional workaround.

Share:
12,612
ARUNBALAN NV
Author by

ARUNBALAN NV

Updated on June 13, 2022

Comments

  • ARUNBALAN NV
    ARUNBALAN NV almost 2 years

    I am trying to invoke my Lambda function by passing parameters as below. it contains apostrophe(').

    https://invoke_url?param=[["kurlo jack's book","Adventure Books",8.8,1]]
    

    Stringifyed to be 'https://invoke_url?param=%5B%5B%229780786706211%22s....`

    I used the mapping below to pass parameter to lambda

      "query": {
        #foreach($queryParam in $input.params().querystring.keySet())
        "$queryParam": "$util.escapeJavaScript($input.params().querystring.get($queryParam))" #if($foreach.hasNext),#end
    
        #end
      }  

    I got following error

    {"message": "Could not parse request body into json: Unrecognized character escape \'\'\' (code 39)\n at [Source: [B@5b70c341; line: 29, column: 65]"}  
    

    i have also tried after removing double quotes from mapping template. But did't work.