Skip to content
GuideAPIANT.aiv2

Error handling and retries

View .md

What happens when an APIANT automation step fails: the automatic retry schedule, which errors are retried, continue-on-error modes, the error output, error-handler subroutines, and the 401 turn-off.

When a step fails, APIANT first retries it if the error looks temporary, then hands the error to an error-handler subroutine if the automation has one, and otherwise stops the run and reports the error. Each step can instead be set to continue past a failure and pass the error on as data.

What happens when a step fails

With the default setting, a failed step goes through these stages in order:

  1. Retry. If the error is retryable, the run is parked and the step is tried again on a fixed schedule.
  2. Step error handler. If the step has an error-handler subroutine, it runs with the error details.
  3. Automation error handler. If the step has no handler, or its handler also fails, the automation's error-handler subroutine runs, if there is one.
  4. Stop. Otherwise the step is marked as failed, the run ends with an error, and an alert is raised.

A step that exceeds the run's time limit fails without retries.

Automatic retries

A retryable failure is retried on this schedule, which is the same for every automation and cannot be changed:

AttemptWaits before it
1Runs immediately
21 minute
32 minutes
45 minutes
510 minutes
630 minutes
71 hour
82 hours
9 (last)4 hours

That is 9 attempts over about 7 hours 48 minutes. While a retry is pending, the run's status is snoozed and no alert is sent. If the last attempt fails, the error goes to the error handlers, or the run fails.

  • A retry runs the failed step again. Steps that already succeeded in that run are not repeated.
  • A failure inside an ordinary automation called synchronously resumes that child run: its steps that already succeeded replay their recorded output instead of running again.
  • A polling automation does not park for retries. A record that fails is not marked as processed, so the next poll picks it up again while the app still returns it.
  • Turning an automation off removes its pending retries.

Which errors are retried

RetriedNot retried
HTTP 429, 500, 502, 503 and 504HTTP 501 and 505, and 4xx responses other than 429
Request and connection timeoutsA domain name that does not exist
Connection refused, reset or dropped mid-responseA request blocked by the platform's network policy
Temporary DNS failures and unreachable hostsValidation errors, such as a value that cannot be converted to a field's type
Lock contention inside the platform

APIANT also keeps a platform-wide list of error-message fragments that are treated as retryable, so an error in the right-hand column, other than a request blocked by the network policy, can still be retried when its message matches that list. An app's connector can also define its own handling for specific responses, which takes precedence over this table. You cannot change the list, or the retry schedule, from your account. If an app returns an error that is clearly temporary and is not being retried, contact APIANT support with the error text and examples of runs that succeeded on a later attempt.

To retry failed runs by hand, see Retries, replays and restarts.

Continuing past a failure

A step's error handling can be set to one of three modes. Ask for it in plain English, for example "if the lookup finds nothing, carry on".

ModeOn failure
Halt (default)Retry, then error handlers, then stop the run
Continue on non-critical error (continueOnNoncriticalError)Continue, unless the failure is an HTTP 5xx or 404, in which case it halts
Continue on any error (continueOnAnyError)Continue, whatever the failure

A step that continues is not retried and does not run an error handler. It is recorded as recovered, counts no task, and its output carries the error so later steps can act on it.

Use Halt for steps that must succeed, such as creating a record. Use a continue mode for lookups that may legitimately find nothing and for checks such as "does this record still exist?".

The error output

Every step output has an error field. It is null when the step succeeded. When a step failed and the run continued, it holds:

FieldContains
error.messageThe error text
error.statusThe HTTP status for an app error, such as 404 or 429; 0 otherwise
error.vendor_payloadThe app's response body, decoded if it is JSON; null if there was none
error.vendor_headersThe app's response headers
error.retryableWhether this kind of error is retryable. It does not mean another retry will happen.

A step that continued also outputs continued_on_error: true.

Follow a continue-mode step with a condition that checks for success first, then routes on the status:

json
{
  "step_id": "lookup_succeeded",
  "type": "condition",
  "if": "steps.lookup_client.output.error == nil",
  "then": [ { "step_id": "update_client", "type": "assembly" } ],
  "else": [
    {
      "step_id": "was_rate_limited",
      "type": "condition",
      "if": "steps.lookup_client.output.error != nil && steps.lookup_client.output.error.status == 429",
      "then": [ { "step_id": "notify_rate_limit", "type": "assembly" } ]
    }
  ]
}

Always check that error is not null before reading error.status. A test that reads error.status on a step that succeeded evaluates as false and takes the else branch without failing the run.

Route on error.status, not on the wording of error.message. Apps change their messages.

Error-handler subroutines

An error handler is a subroutine that runs when a step fails after its retries. It can be attached to one step, to the whole automation, or both.

The handler receives values you map from {{ error }}:

json
"on_error": {
  "subroutine_uuid": "<error handler subroutine id>",
  "input_mapping": {
    "failed_step": "{{ error.step_id }}",
    "status": "{{ error.status }}",
    "message": "{{ error.message }}",
    "detail": "{{ error.vendor_payload }}"
  }
}

Inside the handler, these arrive as {{ trigger.input.failed_step }}, {{ trigger.input.status }} and so on. In the input mapping, error is never null, and error.step_id names the step that failed.

When the handler finishes, the failed step is marked recovered and the run continues with the next step. The step's output then holds error, on_error_recovered: true, the handler's subroutine_uuid, and the handler's step outputs under outputs. An automation-level handler reports doc_on_error_recovered instead.

Typical handlers post the failure to a team channel, write the record to a review table, or create a ticket. See Subroutines and calling automations.

When an app returns 401

A 401 response usually means a connection's credentials were revoked or expired. When a run ends with an error because a step got a 401, APIANT turns the automation off and queues the notice "A 401 error turned off this automation; reconnect the account." Runs stop until you reconnect and turn the automation back on.

  • A 401 on a step set to continue past errors, or one recovered by an error handler, does not turn the automation off.
  • If refreshing the connection's token also fails, or the app returns a 403 saying the token lacks a required permission, the connection is marked as needing to be reconnected. Runs keep failing until you reconnect.
  • Some apps return 401 for rate limits or quotas. APIANT keeps a platform-wide list of such domains, where a 401 is handled as an ordinary error instead. The list is managed by APIANT; contact support with evidence if an app belongs on it.

See Connecting accounts.

Alerts and turning off on any error

When a run ends with an error, the alert goes through the automation's alert settings, found in the dashboard gear menu under Processing > Alert handling:

SettingDefaultEffect
Email me on any alertOnQueues an alert email for this automation's errors
Turn off automation on any alertOffTurns the automation off at its first error, not only on a 401
Alert mappings…NoneRewrites or suppresses alert messages that match a pattern

Queued alert emails, including the 401 notice, are delivered according to Alert email delivery in the account menu's Settings…: Immediately, Hourly, Daily or Never. The default is Never, and with Never, queued alerts are discarded rather than sent. Set it to Immediately, Hourly or Daily to receive error and 401 emails.

See Error alerts for alert mappings, suppressed alerts and delivery.

Stopping a record on purpose

To fail a record deliberately, for example when required data is missing, use the Flow Control action Halt data row processing with error with your own message. The record ends with that error and follows the alert settings above. To skip a record without an error, use Halt data row processing. See Conditions, loops and parallel branches.

Troubleshooting

SymptomLikely causeWhat to do
An automation turned itself offA 401, or Turn off automation on any alert is onReconnect the app if it was a 401, then turn the automation on
A temporary error was not retriedThe step uses a continue mode, the error class is not retryable, or the automation pollsCheck the step's error handling mode and the error's status
No error emails arriveAlert email delivery is set to NeverChange it under Settings… in the account menu
A run shows green but data is missingA continue-mode step failed and was recoveredLook for recovered steps in the run and check their error output
A condition on error.status always takes elseThe test reads error.status without checking error != nil firstAdd the error != nil && guard

Next steps

Related docs

Last updated September 15, 2026