How-to library · Developer docs

How-to library

Task-shaped pages: a title that starts with a verb, the situation in a few lines, the steps, the working code in both engines, and why this way rather than another. Found from a search, done, and left.

Debug a job run that failed halfway

Read the batch log in order: the event, the first failed action and what it received, then what already happened. Fix the cause, and re-run only a job that is safe to run twice.

Context

Context. A batch shows error: some of its actions ran and the rest did not. Before fixing anything, find out three things: which action failed and why, what the actions before it already did, and whether running the job again is safe. The answers are all in the batch log, and the order you read it in matters.

Steps

  1. Open the batch in Customization › Orchestration › Batch Logs. If there is no failed batch to open, check the job's batch persistence: never and success discard failed runs, and nothing can be recovered. Set it to always and wait for the next failure.
  2. Read the event first. Is it the record, method or request you expected? A job that failed on the wrong record is a trigger problem, not an action problem.
  3. Find the first action with status error and read its output: a template error with its line, an HTTP status and response, a record not found, an invalid address. The actions after it have no rows, which shows where it stopped. In a loop, each element has its own row and status.
  4. Read what it received. The output of the actions before it shows what they found and rendered: the criteria a Retrieve records used and how many records came back, the body an HTTP request sent. Most failures are a value from an earlier action that was empty or not what the template expected.
  5. List what already happened. Every action before the failure did its work, and none of it is undone: records created or changed, requests sent to other systems, emails queued. Write that list down before you touch anything.
  6. Reproduce it. Replace the failing action's template with a Render template that prints the values it uses, or make a copy of the job with only the actions up to the failure, and run it against the same record.
  7. Fix the cause, then decide how to finish the work (below).

Code

A Render template placed just before the failing action, printing what it is about to use; the output appears in the batch log:

Template code
event: {$event->getRecordId()}
found: {$runData->get('find-contact')->records|count}
first: {if $runData->get('find-contact')->record}{$runData->get('find-contact')->record->getId()}{else}none{/if}
custom data: {$customData->get('payload')|json_encode}
event: {{ event.getRecordId() }}
found: {{ runData.get('find-contact').records|length }}
first: {{ runData.get('find-contact').record ? runData.get('find-contact').record.getId() : 'none' }}
custom data: {{ customData.get('payload')|json_encode }}

The failures that account for most half-finished batches, and where their message points:

Output of the failed actionUsual cause
Syntax error in template … on line …A hand-typed JSON body in Smarty ({" starts a tag), or a method chained onto a function call
Method … does not exist in … Api\Response …A page-template method on a job's record, such as getAreaText(); use getActiveRevision()->getAreaText()
Could not convert PHP value … to type 'datetime'A date given as text in Retrieve records criteria; select by date in a template instead
An HTTP status outside 2**, with the responseThe other system refused it; its response says why. A 404 or 409 you meant to handle needs adding to the accepted codes
Address is invalidA Send mail address rendered empty or malformed
Could not find record with id …An Update or Delete record whose source id rendered wrong, or a record deleted since

Why this and not that

Re-run from Batch Logs only when the job is safe to run twice. A re-run does not resume: it deletes the batch's action results and output files and runs the job again from its first action, so everything before the failure happens a second time. That is harmless for a job built to be idempotent (how) and wrong for one that creates records or sends emails without checking. When it is not safe, finish the work another way: correct the record and let the next event run the job, or copy the job, remove the actions that already happened, and run the copy once.

Keep the evidence until you are done. Batches are deleted after 30 days by default, and a re-run replaces the failed batch's log with the new run's. Note the batch id and copy the failing action's output before re-running. For a scheduled job, the next run is the re-run: if it selects the work still to do, as Scheduled work recommends, fixing the cause is all that is needed.

Go deeper

Was this page helpful?

Your answer goes to the docs team.