Debugging Common Actions on Google Errors

If you’ve spent any time testing your Action in the Actions simulator, you’ve probably seen various error messages and haven’t always been sure how to resolve them. In this post, we cover some of the most common errors, as well as provide strategies on how to make you a more efficient developer and make your Actions more robust.

Final response must be set

Let’s start with one of the most common errors that developers are confused about:

“MalformedResponse: ‘final_response’ must be set”

The error message sounds a bit cryptic, but it’s explaining that the JSON response the Actions on Google platform received from your Action isn’t well-formed. In this case, the AppResponse doesn’t have a value for the final_response field.

The simulator prints the error message in the “ERRORS” tab. If you click on the “RESPONSE” tab, you will get more detailed information about the JSON response provided by your Action.

In this case, the error was caused by an empty response from Dialogflow. There are several possible reasons why Dialogflow didn’t provide a valid response, including not having a static response configured for that intent:

You will also get the same error message if the Dialogflow intent has been configured with a webhook for fulfillment, but the agent doesn’t have any fulfillment enabled under the “Fulfillment” menu.

If fulfillment has been enabled for any of the agent intents, then you need to have at least one of the fulfillment options enabled.

Common errors

Another common issue is that your fulfillment doesn’t provide the correct kind of response or provides no response at all.

In the simulator, click on the “View logs” link to see the Stackdriver logs associated with your Action project. You can filter the logs by error type or search for error messages.

If you are not using Google Cloud for fulfillment, then you’ll also need to look at the logs of your hosting platform for any error messages.

If you do find errors, it could mean any of the following might apply:

  • Your fulfillment code has a logic error
  • The fulfillment isn’t using the Actions on Google client library correctly
  • Your code might have crashed
  • The hosting platform of your fulfillment became unresponsive

If you are using the Inline Editor in the DialogFlow fulfillment page, use the “View execution logs in the Firebase console“ link to view the logs for the function fulfillment. If you are using your own Cloud Function for Firebase, check the Firebase console for the logs.

Also, take a look at the health section of the Actions console for your project to track metrics related to the quality and health of your Action.

Error handling with the client library

The Actions client library is a great convenience for developers who don’t want to deal with the underlying JSON protocol of the Actions on Google platform. However, it’s important that you follow best practices and comply with the requirements of the various kinds of responses.

To start, it is very important to ensure that you have an associated intent handler for every Dialogflow intent configured with fulfillment. If you don’t, you might get an error message in the logs that looks like the following:

“Dialogflow IntentHandler not found for intent:”

You can fix this by simply adding a new intent handler:

app.intent(‘Default Welcome Intent’, conv => {
  conv.ask(‘Welcome...’);
});

Note: The Dialogflow intent names are case-sensitive.

To catch any exceptions in the intent handlers, you should use the global app.catch method to provide a response. In this example, the error is logged and the Action is closed with a message:

app.catch((conv, e) => {
  console.error(e);
  conv.close(‘Oops. Something went wrong.’);
});

Another common issue is mixing conv.ask and conv.close API methods for doing responses. Either the response will continue the conversation, which means you should only be using conv.ask, or the conversation is ending, which means you should only use conv.close.

For handling exits, like responding to the actions_intent_CANCEL event, you should only use a simple response with conv.close or you will get this simulator error:

MalformedResponse
expectUserResponse must be false for cancel intent response.

If you are using rich responses, ensure you always provide at least some text as a simple response or you might get this error:

MalformedResponse
expected_inputs[0].input_prompt.rich_initial_prompt: ‘rich_response’ must contain at least one item.

The rich responses developer guide lists the requirements for each kind of response.

If your simple response doesn’t contain any content or valid SSML, then you might get an error like this:

MalformedResponse
expected_inputs[0].input_prompt.rich_initial_prompt.items[0].simple_response: ‘display_text’ must be set or ‘ssml’ must have a valid display rendering.

If you are using helpers intents, then some of the intents options can only be configured with their own responses without any additional simple responses.

If your fulfillment is making any asynchronous calls like invoking an external API, then you need to ensure your intent handler uses a Promise to provide the response; otherwise, the intent handler might complete without providing a response. Take a look at our GitHub sample on the correct way to invoke external APIs.

If everything else fails

Even when you have followed all the best practices and you have extensively tested your Action, unexpected code paths or platform issues might still occur when it runs in production.

To ensure your users always have a good experience, your Action should expect and handle these kinds of conditions gracefully.

An easy way to have Dialogflow help you with this is to configure each intent to use the default text response as a static fallback when anything bad happens with fulfillment.

Here, you see an intent that has been configured to respond with “Oops! Something went wrong. Please try again later.” when the webhook fails:

This works because Dialogflow falls back on the intent configuration when the webhook call fails for any reason. In this case, it provides a static response and then ends the conversation. If the webhook call succeeds, the fulfillment provides the response dynamically and decides if the conversation should end.

Start debugging

So, try these hints for finding and fixing errors in your Actions. If you need more help, post a question on Stackoverflow, where our team will help you with an answer.

Also, join our developer community and share your experiences: https://g.co/actionsdev

We look forward to trying out your Actions!

Want More? Join the Actions on Google developer community program and you could earn a $200 monthly Google Cloud credit and an Assistant t-shirt when you publish your first app.