When devices or requests don't work as expected, it is important to provide
good error handling and communication for your users so they understand what
happened, and whenever possible, how to correct it. Make sure you think through
possible failure scenarios and how your device should respond: What if a user
interrupts a task in progress? What if a user requests an action from a device
while it is offline? Planning for these issues and helping your user recover
from them can avoid user frustration and creates a higher quality experience
for your devices.

This guide provides some examples of intent responses that handle errors. See
the [Errors and exceptions](https://developers.home.google.com/cloud-to-cloud/intents/errors-exceptions) to
review the valid `errorCode` values for error and exceptions.

> [!NOTE]
> **Note:** While responding to intent requests with an error status, you still need to return the HTTP status code `200`.

## Example 1: Error response for `EXECUTE` intent

An end user has two smart lights installed in their living room. The user
issues a command "turn on living room lights" and Google sent an `EXECUTE`
intent to your fulfillment URL. You found that the user's devices are offline
and not controllable, so your fulfillment returns an `EXECUTE` response with
`status` `ERROR` and `errorCode` `deviceOffline`.

This example demonstrates how to return an `EXECUTE` response with an
`errorCode` from a light device as described earlier:

```
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "light-device-id-1"
        ],
        "status": "ERROR",
        "errorCode": "deviceOffline"
      },
      {
        "ids": [
          "light-device-id-2"
        ],
        "status": "ERROR",
        "errorCode": "deviceOffline"
      }
    ]
  }
}
```

The Google Assistant prompts the user with "the *device* are
not available right now" after receiving the response. Remember that you still
need to send offline state for devices in report state after sending
`errorCode` `deviceOffline` in `EXECUTE` response.

## Example 2: Non-blocking exception for `EXECUTE` intent

A user tries to lock the smart lock on their front door using
Assistant. You can successfully control their lock but
you find the device battery is low, so your fulfillment returns an `EXECUTE`
response with `status` `SUCCESS` and `exceptionCode` `lowBattery`.

This example demonstrates how to send a `EXECUTE` response with an
`exceptionCode` from a lock device as described earlier:

```
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [{
      "ids": ["lock-device-id-1"],
      "status": "SUCCESS",
      "states": {
        "on": true,
        "online": true,
        "isLocked": true,
        "isJammed": false,
        "exceptionCode": "lowBattery"
      }
    }]
  }
}
```

The Assistant prompts user with "the *device* has low
battery" after receiving the response.

## Example 3: Proactive error notifications

In some cases, it can be helpful to alert users to an error, particularly for
functions that are users expect to complete automatically. For traits that
support proactive notifications, you can proactively notify the user while an
error happens if you have implemented smart home
[proactive notifications](https://developers.home.google.com/cloud-to-cloud/integration/notifications).

A smart dryer is running, and someone opens the door before the cycle finishes.
You can call the Google Home Graph API
`reportStateAndNotifications` method to send a proactive notification with an
`errorCode`:

This example demonstrates how to send a proactive notification with an
`errorCode` from a dryer device as described earlier:

`POST https://homegraph.googleapis.com/v1/devices:reportStateAndNotification`

```
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "agentUserId": "agent-user-id",
  "eventId": "unique-event-id",
  "payload": {
    "devices": {
      "notifications": {
        "dryer-device-id": {
          "RunCycle": {
            "priority": 0,
            "status": "FAILURE",
            "errorCode": "deviceDoorOpen"
          }
        }
      },
      "states": {
        "dryer-device-id": {
          "isRunning": false,
          "isPaused": true
        }
      }
    }
  }
}
```

The Assistant prompts the user with "the *device* door
is opened" after receiving the notification. You can send the corresponding
device states alongside notifications in the same payload.

## Example 4: Follow-up notification

For traits commands that support follow-up notifications, you can send a
follow-up notification to the user while an error or an exception happens, if
you have implemented smart home
[follow-up notifications](https://developers.home.google.com/cloud-to-cloud/integration/notifications).

A user issues a command to close their garage door, but the door is jammed
while closing. You can send a follow-up notification with an `errorCode`:

`POST https://homegraph.googleapis.com/v1/devices:reportStateAndNotification`

```
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "agentUserId": "agent-user-id",
  "eventId": "unique-event-id",
  "payload": {
    "devices": {
      "notifications": {
        "door-device-id": {
          "LockUnlock": {
            "priority": 0,
            "followUpResponse": {
              "status": "FAILURE",
              "errorCode": "deviceJammingDetected",
              "followUpToken": "follow-up-token-1"
            }
          }
        }
      },
      "states": {
        "door-device-id": {
          "openPercent": 70
        }
      }
    }
  }
}
```

The Assistant prompts the user with "the *device* is
jammed" after receiving the notification. You can send the corresponding
device states with notifications in the same payload.

For more information and detailed `errorCodes`, see the
[Errors and exceptions](https://developers.home.google.com/cloud-to-cloud/intents/errors-exceptions)
reference documentation.