FlowsGuide

The On error step and the Preprocessor

Two steps of a flow live outside its chain. The On error step runs once when the flow fails, to tell someone or record what happened. The Preprocessor runs first when the flow is called through an API endpoint, and turns the raw request into the flow’s inputs. Each flow has at most one of each, and both sit as cards at the top of the canvas instead of nodes on the line.

What you will learn
  • Add an On error step as a script, an e-mail or a subflow
  • Read the error’s message, code and failing step in it
  • Know exactly when On error runs — and when it does not
  • Map an API request to the flow’s inputs with a Preprocessor

Two cards above the canvas

At the top-left of the canvas sit two quiet cards: On error (“Runs if a step fails — to warn someone.”) and Preprocessor (“Turns an API call into the flow’s inputs.”). Empty, each shows Add. Once set, the card shows the step’s logo and name — click it to open the step, ⋯ to remove it. In a run, the card carries the step’s status only when it actually ran.

A step fails, the run stops there, and the On error card at the top runs once with the error.

Neither step has edges, and nothing in the chain can bind to them. That is deliberate: they answer events — a failure, an API call — not a position in the flow.

Add an On error step

  1. Choose what it is

    Click Add on the On error card. Under Write code pick Python, TypeScript or JavaScript (“Runs with the error: message, which step failed…”); under Or pick Email (“Send an e-mail saying what failed”) or Subflow (“Run another flow with the error”).

  2. Read the error

    The step’s panel opens on What this step can read: error.message, error.stepName, error.stepId, error.code and error.name. Use them in an input set to Expression — click one to copy it. A new script step arrives already bound: message ← error.message and step ← error.stepName.

  3. Send it somewhere

    An e-mail step binds the error into its template values; a subflow passes it to one flow that many of your flows reuse. Scripts have no network, so to reach a chat tool use an e-mail or a subflow with an HTTP Request step.

on_error.py
def main(message: str = "", step: str = ""):
    print(f"{step} failed: {message}")
Expected outputThe On error step’s log after a step called “Charge card” failed
Charge card failed: card declined

When it runs

What happenedOn error runs?
A step failed for real (after its last retry, without Continue on error)Yes, once
The flow hit its time limitYes — with at least a minute to finish
The Preprocessor failedYes, with stepName “Preprocessor”
A step failed with Continue on errorNo — the run is Completed with errors
A Stop flow if fired (any final status)No
Someone cancelled the run, or an approval was rejectedNo
Everything succeededNo

The run stays failed with its original error: whatever the On error step does, and even if it fails itself, the run’s status and error are the failing step’s. On the canvas it reads Ran because the flow failed. Project-level alerts are separate and fire on their own rules; use On error for what is specific to this one flow.

The Preprocessor

When a flow is published as an API endpoint, the caller decides the shape of the request — a webhook from a shop sends its own JSON. A Preprocessor adapts it. It is a script (Python, TypeScript or JavaScript) whose main(request) receives method, path, query, headers, rawBody and body (parsed from JSON or a form) and must return an object: that object becomes the flow’s inputs, as if they had been typed at Start.

preprocessor.py
def main(request: dict):
    # request: method, path, query, headers, rawBody, body
    body = request.get("body") or {}
    return {
        "orderId": body.get("order", {}).get("id"),
        "source": request["query"].get("source", "api"),
    }
  • It runs only for calls through an API endpoint. Runs from the editor, a schedule or another flow skip it.
  • The endpoint does no parameter mapping for such a flow — the whole request goes to the Preprocessor.
  • Test with a saved request runs your current code against one of the flow’s recent calls and shows Inputs it produced. With no calls yet it says No calls yet — call the flow’s endpoint once.
  • Every endpoint call’s request is kept with the run for 30 days (bodies up to 1 MB), and the run can be re-run with it.

Rules and error codes

  • One On error step per flow (on_error_duplicate) and one Preprocessor (preprocessor_duplicate).
  • On error is a script, an e-mail or a subflow, and cannot use Continue on error. The Preprocessor is a script and cannot also be the On error step.
  • A Preprocessor that throws, times out or returns something that is not an object fails the run with preprocessor_failed.