Non-retriable errors

Stop retries when another attempt cannot fix the error.

Throw NonRetriableError when the same work will fail again, such as an invalid ID or a record that will not become available. Inngest skips the remaining retries for the step or function where you throw it. Use a standard Error for a timeout or another temporary failure so Inngest can retry.

Stop retries for a step

This TypeScript v4 example uses the inngest client from the Quick start. Replace the URL with your service endpoint.

import { NonRetriableError } from "inngest";

export const loadOrder = inngest.createFunction(
  {
    id: "load-order",
    triggers: { event: "shop/order.requested" },
  },
  async ({ event, step }) => {
    return await step.run("load-order", async () => {
      const response = await fetch(
        `https://api.example.com/orders/${event.data.orderId}`
      );

      if (response.status === 404) {
        throw new NonRetriableError("order does not exist");
      }
      if (!response.ok) {
        throw new Error(`order API returned ${response.status}`);
      }

      return response.json();
    });
  }
);

If the API returns 404, Inngest marks load-order failed without trying that step again. Other errors follow the configured retry policy. Use 404 this way only when the order cannot appear later.

Decide whether the function fails

When a step.run() fails, it throws a StepError into the function, even if its handler threw NonRetriableError. The caught value is not the original NonRetriableError instance. Catch the failed step to run a fallback or compensation in another step. If you leave it uncaught, the function fails. A configured failure handler then handles that final failure.

Throwing NonRetriableError outside a step stops retries for the function itself. Use this for validation before any step runs:

if (!event.data.orderId) {
  throw new NonRetriableError("orderId is required");
}

Do not catch a failed step and throw a standard Error unless you want the function code to retry. For a recovery example, see Rollbacks.

Keep the original cause

When you convert an error from your app, pass it as cause so the failure retains diagnostic context:

throw new NonRetriableError("orderId is invalid", { cause: error });

The TypeScript v4 constructor takes a message and an optional { cause } object. Choose this error only after you know another attempt cannot succeed. It does not undo external calls that already completed.