Debugging Common Actions on Google Errors

Leon Nicholls
Sep 18, 2018 · 6 min read

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:

MalformedResponseexpectUserResponse 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:

MalformedResponseexpected_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:

MalformedResponseexpected_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.

Google Developers

Engineering and technology articles for developers, written…

Google Developers

Engineering and technology articles for developers, written and curated by Googlers. The views expressed are those of the authors and don't necessarily reflect those of Google.

Leon Nicholls

Written by

Former Google Assistant Developer Relations Engineer

Google Developers

Engineering and technology articles for developers, written and curated by Googlers. The views expressed are those of the authors and don't necessarily reflect those of Google.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store