Runtime verified Test scripts included

Syntax

RaiseError(message[, skipSubscriber, apiErrorCode, apiErrorNumber, preserveDataExt])  →  void
1–5 arguments

Parameters

Name Type Required Description
message string Yes Error message
skipSubscriber string | boolean | number No Skip only the current subscriber and continue the job, rather than stopping it
apiErrorCode string No Custom API error code
apiErrorNumber number No Custom API error number
preserveDataExt boolean No Retain data extension writes made before the error, even when the subscriber is skipped

Example

%%[
  VAR @code
  SET @code = QueryParameter("code")
  IF Empty(@code) THEN
    RaiseError("No code supplied")
  ENDIF
]%%

Renders nothing at all when the guard fires: the request ends with HTTP 422 and a fixed failure notice, and the supplied text appears nowhere in it.

The realistic pattern is to raise inside a send, where the second argument decides whether the job stops or only the current subscriber is skipped.

%%[
  VAR @rows
  SET @rows = LookupRows("Coupons", "Status", "free")
  IF RowCount(@rows) == 0 THEN
    RaiseError("No coupon left for this subscriber", true)
  ENDIF
]%%

On a landing page that second argument changes nothing you can observe — see below.

Return value

void — nothing is returned. On a landing page the request is abandoned and the body is replaced by a fixed failure notice rather than the message you passed.

There is no closed set of sentinel values to test for; the function answers with an aborted request rather than a value.

Behaviour

It is not a graceful abort on a landing page. The request ends with HTTP 422 and the response body is a short fixed failure notice. That is the same status and the same body every other aborting AMPscript call produces.

Everything written before the call is discarded. Two marker lines written immediately before the call, the surrounding block’s own start marker, and even a control line written at the very top of the page — one that renders on every other request — were all missing from the response. Nothing that ran earlier reaches the browser.

Nothing after the call runs. The marker line placed after the call and the block’s closing marker were both absent.

The caller never sees the message. Four separate runs passed four distinct messages and none of them appeared anywhere in the response. Whatever you write there is for the send log, not for the visitor.

The second argument accepts three spellings interchangeably. Unquoted true, unquoted false, the numbers 1 and 0, and the quoted "true" were each run in isolation and all five produced the identical response. That is why the type is written as three alternatives rather than as a boolean.

Telling it apart from an unrelated failure

A control run in the same deployment aborted for a reason with nothing to do with this function — a wrong argument count on an unrelated string function. Its response was byte-for-byte the same: HTTP 422, same body length, same text.

Run Status Body
A call to this function 422 fixed failure notice
An unrelated aborting call 422 the same fixed failure notice

So from outside the page the two cannot be distinguished. If you need a visitor-facing error, render your own message and stop the flow with an IF branch instead — this function gives the caller nothing to read.

Show test script
%%[
  VAR @b
  SET @b = RequestParameter("b")

  /* known-good control: renders on every request, so a run of HTTP 422s
     can be told apart from a broken deploy */
  OutputLine(Concat("CTRL=[", Uppercase("ok"), "]"))
  OutputLine(Concat("GATE=[", @b, "]"))

  /* the markers before and after the call are the point: NEITHER is
     delivered, and neither is the control line above */
  IF @b == "re1" THEN
    OutputLine(Concat("--- re1 start ---"))
    OutputLine(Concat("RE_BEFORE=[written-before]"))
    RaiseError("probe-msg-one")
    OutputLine(Concat("RE_AFTER=[written-after]"))
    OutputLine(Concat("--- re1 done ---"))
  ENDIF

  /* all three spellings of the flag are accepted and all reach the same
     abort, so the parameter is not boolean-only */
  IF @b == "re2t" THEN
    OutputLine(Concat("--- re2t start ---"))
    RaiseError("probe-msg-two-true", true)
    OutputLine(Concat("--- re2t done ---"))
  ENDIF

  IF @b == "re2f" THEN
    OutputLine(Concat("--- re2f start ---"))
    RaiseError("probe-msg-two-false", false)
    OutputLine(Concat("--- re2f done ---"))
  ENDIF

  IF @b == "re2n1" THEN
    OutputLine(Concat("--- re2n1 start ---"))
    RaiseError("probe-msg-num-one", 1)
    OutputLine(Concat("--- re2n1 done ---"))
  ENDIF

  IF @b == "re2n0" THEN
    OutputLine(Concat("--- re2n0 start ---"))
    RaiseError("probe-msg-num-zero", 0)
    OutputLine(Concat("--- re2n0 done ---"))
  ENDIF

  IF @b == "re2q" THEN
    OutputLine(Concat("--- re2q start ---"))
    RaiseError("probe-msg-quoted-true", "true")
    OutputLine(Concat("--- re2q done ---"))
  ENDIF

  IF @b == "re5" THEN
    OutputLine(Concat("--- re5 start ---"))
    RaiseError("probe-msg-five", true, "PROBECODE", 4321, true)
    OutputLine(Concat("--- re5 done ---"))
  ENDIF

  IF @b == "re0" THEN
    OutputLine(Concat("RE0_START=[x]"))
    RaiseError()
    OutputLine(Concat("RE0_DONE=[x]"))
  ENDIF

  IF @b == "re6" THEN
    OutputLine(Concat("RE6_START=[x]"))
    RaiseError("probe-msg-six", true, "PROBECODE", 4321, true, "extra")
    OutputLine(Concat("RE6_DONE=[x]"))
  ENDIF

  /* the control gate: it aborts for a reason that has nothing to do with
     this function, yet the caller sees exactly the same response */
  IF @b == "ctlabort" THEN
    OutputLine(Concat("CTL_START=[x]"))
    OutputLine(Concat("CTL=[", Uppercase(), "]"))
    OutputLine(Concat("CTL_DONE=[x]"))
  ENDIF
]%%

Every gate in the script returns HTTP 422

What a page cannot show is the documented purpose: stopping an email job, skipping a single subscriber while the job continues, and the fate of the API error code and number. All of those are properties of a send and were not exercised here. The official reference describes only send behaviour and makes no landing-page claim, so the abort above is undocumented territory rather than a contradiction.

Availability

Platform Available
Marketing Cloud Engagement Yes
Marketing Cloud Next Yes, from API 67.0

See also