> For the complete documentation index, see [llms.txt](https://developers.make.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.make.com/custom-apps-documentation/best-practices/base/error-handling.md).

# Error handling

Every API endpoint can return an error, so every app should implement error handling. Good error handling means the user immediately understands *what* went wrong and *how* to fix it, instead of seeing a bare status code.

This page collects best practices. For the directive syntax and the full list of error types, see the [`error`](/custom-apps-documentation/component-blocks/api/handling-responses/error.md) and [`valid`](/custom-apps-documentation/component-blocks/api/handling-responses/valid.md) directive references.

{% hint style="warning" %}
When the service returns an HTTP error, it is not possible to evaluate it as a success.
{% endhint %}

## Write clear, actionable error messages

The error message should be clear and user-friendly, and it should match the structure of the service's response. Always include the status code, and pull the message (and any error code) from the response body.

For example, instead of `Error: contact_not_found`, the message should be `[404] The specified contact was not found.`

For a response shaped like this:

{% tabs %}
{% tab title="JSON response" %}

```json
{
    "error": {
        "code": "E101",
        "message": "The company with the given ID does not exist."
    }
}
```

{% endtab %}
{% endtabs %}

handle it like this:

```jsonc
{
  "response": {
    "error": {
      "message": "[{{statusCode}}] {{body.error.message}} (error code: {{body.error.code}})"
      // Outputs: "[404] The company with the given ID does not exist. (error code: E101)"
    }
  }
}
```

{% hint style="info" %}
The error object in this example contains the `code` and `message` fields. It is also important to show the status code of the error. This can be accessed using the `statusCode` keyword.
{% endhint %}

## Rely on default error types, customize only when needed

When a response returns a 4xx or 5xx status, Make automatically treats it as an error and assigns a sensible default error type and message based on the status code, so you don't need to handle these statuses manually.

Add an `error` directive when you want to **customize the message** (recommended — the defaults are generic) or **override the default type** for a specific status. For the exact status-to-type and status-to-message mapping and the available types, see the [`error`](/custom-apps-documentation/component-blocks/api/handling-responses/error.md) directive reference.

## Rate limit errors (429)

An HTTP `429` is an API rate-limit error. Make handles it as a `RateLimitError` **by default**, so in most cases you don't need to do anything.

This matters because of how the two error types differ in a scheduled scenario:

* A plain `RuntimeError` counts toward the scenario's consecutive-error limit (3 by default). Once that limit is reached, scheduling is switched off and the user has to turn it back on manually.
* A `RateLimitError` instead lets the scenario retry automatically, so a temporary rate limit doesn't disable the scenario. For the exact retry schedule, see [Automatic retry of incomplete executions](https://help.make.com/automatic-retry-of-incomplete-executions).

Because `429` is already a `RateLimitError`, you only need the `error` directive if you want to customize the message or override the type. When you set only a `message` for status `429` (and don't override `type`), the type stays `RateLimitError`:

{% tabs %}
{% tab title="Example code to customize the 429 error message" %}

```javascript
{
  "response": {
    "error": {
      "429": {
        "message": "{{body.message}}"
      }
    }
  }
}
```

{% endtab %}
{% endtabs %}

## Errors returned with an HTTP 200 status

Some APIs return `200` even for failed requests — either with an error flag in the body, or with an empty result for a request that should have failed. Make treats any status below 400 as success, so you must detect these cases yourself with the [`valid`](/custom-apps-documentation/component-blocks/api/handling-responses/valid.md) directive.

A common case: a **Get a/an \[item]** module built on top of a search endpoint (because the service has no dedicated get endpoint). An invalid ID then returns an empty `200` instead of an error.

```jsonc
{
	"url": "/items",
	"method": "GET",
	"qs": {
		"id": "{{parameters.itemId}}"
	},
	"response": {
		"valid": {
			// Mark response as invalid if no item or no item ID is returned,
			"condition": "{{body.items[1].id}}",
			"message": "Item with the given id does not exist."
		},
		"output": "{{body.items[1]}}"
	}
}
```

See the [`valid`](/custom-apps-documentation/component-blocks/api/handling-responses/valid.md) directive reference for how it resolves the error message and type.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.make.com/custom-apps-documentation/best-practices/base/error-handling.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
