Search code examples
aws-lambdaamazon-lex

AWS Lex receives Invalid Response from lambda function - Can not construct instance of IntentResponse


Using Java8 in eclipse AWS SDK, I've created and uploaded a lambda function that is hooked in upon fulfillment of my lex intent. Lambda has not problem receiving JSON request and parsing. Then, I format a simple "Close" dialogAction response and send back to lex and receive the following error from the Test Bot page in the lex console:

    An error has occurred: Received invalid response from Lambda: 
    Can not construct instance of IntentResponse: 
    no String-argument constructor/factory method to deserialize 
    from String value
    ('{"dialogAction
    {"type":"Close","fulfillmentState":"Fulfilled","message":
    {"contentType":"PlainText","content":"Thanks I got your info"}}}') 
    at [Source: "{\"dialogAction\":
    {\"type\":\"Close\",\"fulfillmentState\":\"Fulfilled\",\"message\":
   {\"contentType\":\"PlainText\",\"content\":\"Thanks I got your 
   info\"}}}";line: 1, column: 1]

It seems to have a problem right away with the format (line 1, column 1), but my JSON string looks ok to me. Before returning the output string in the handleRequest java function, I am writing the it to the Cloudwatch log and it writes as follows:

{
   "dialogAction": {
        "type": "Close",
        "fulfillmentState": "Fulfilled",
        "message": {
            "contentType": "PlainText",
            "content": "Thanks I got your info"
        }
    }
}

Things I've tried:

  • Removing the message element as it's not required
  • Adding in non-required properties like sessionAttributes, responseCard, etc
  • removing the double quotes
  • replacing double quotes with single quotes
  • hardcoding json from sample response format message in documentation

Is there something hidden at the http headers level or is java8 doing something to the JSON that is not visible?


Solution

  • Not sure if this is because I'm using Java8 or not, but a return value of "String" from the RequestHandler class handleRequest method will not work. Yes, String is an object, but the constructors on the Lex side are expecting an "Object". I was converting my lex response POJO to a String before returning it in the handleRequest method. That was my mistake.

    I fixed it by changing the return type of the handleRequest method to be "Object" instead of "String".

    public Object handleRequest(Object input, Context context)
    

    instead of

    public String handleRequest(Object input, Context context) 
    

    You also have to implement the

     public class LambdaFunctionHandler implements RequestHandler<Object, Object>
    

    not

    public class LambdaFunctionHandler implements RequestHandler<Object, String>
    

    This solved my issue.