For the complete documentation index, see llms.txt. This page is also available as Markdown.

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 and valid directive references.

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:

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

handle it like this:

{
  "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)"
    }
  }
}

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.

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

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:

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

See the valid directive reference for how it resolves the error message and type.

Last updated