DomainRuntimedocs
Working with data
GuideWhat works todayReviewed 2026-09-22

Error handling

Failing on purpose, what the caller sees, and which errors are worth retrying.

The behavior on this page runs in production today. Error codes of your own on thrown errors are planned.

Four kinds of error

KindExampleWhat the caller getsRetry?
Rejected inputa field fails the action's input schemaaction_contract_validation_failed; your code did not runno — fix the input
Your code decided nothrow new Error("Managers only")the execution fails with action_failed and your messageno
Your code has a buga TypeError, or an output that fails outputaction_failed or execution_output_invalidno — fix the action
The platformthe result took longer than 110 s, a network dropa 5xx code such as execution_result_timeoutyes, with the same request id

Only the last kind is worth retrying automatically, and retrying with the same request id never runs your code twice.

Failing on purpose

Throw. The message is what the caller sees:

async execute({ input, runtime }) {
  if (!runtime.auth.user) throw new Error("Sign in to place an order");
  const { orders_order } = await runtime.query({
    orders_order: { $: { where: { id: input.orderId } } },
  });
  if (orders_order[0]?.status !== "open") throw new Error("This order is already closed");
  // ...
}

Throw before your first runtime.tx. An error after a tx commits leaves that write in place.

What reaches the caller

An action call answers with its execution. A failed one carries status: "failed", the code action_failed, and your message, truncated to 1000 characters. There is no stack trace, in any environment.

Messages reach your users, so write them for people, and never put secrets, tokens or internal ids in them.

try {
  await db.actions.orders.place({ orderId, total });
} catch (error) {
  toast(error.message);   // "This order is already closed"
}
Planned. Throwing an error with a stable code of your own (for example order_closed) so the client can branch without matching messages.

Reads that fail

A query that fails — too slow, malformed — returns an error from useQuery instead of data. Hidden objects are not an error: they are absent. See Errors for the codes.

Workflows

When a workflow run gives up, its execution fails with workflow_failed. Steps that finished stay finished: design each step so the run can be retried or compensated.

Finding out what happened

Every call has an execution: GET /executions/{id} has its status, output and error. See the HTTP API.

On this page