Skip to main content

Workflow events

See How workflows work.

Task walkthrough: Run events on job outcomes. This page is the full configuration and troubleshooting reference.

An event fires a command in response to a job outcome — for example, sending a notification when a job fails, or triggering another action when a job finishes late. Events are configured per job; workflows can also carry schedule-level events.

Event trigger types​

Trigger (eventTriggerType)Fires based onKey settings
Job status (jobStatus)The job reaching a specific statusjobStatus (see values below)
Job exit description (jobExitDescription)A comparison against the job's termination description — see belowcomparisonOperator, comparisonValue, plus comparisonEndRange when the operator is Range
Completion Expression (jobCompletionExpression)A custom expression — configurable but not yet active, see belowexpression

Every event carries a command to run and an optional frequency that scopes when it applies.

Scoping an event to one frequency​

An event's optional Frequency (Optional) picker scopes it to one of the job's own frequencies: the event is kept only on instances built for that frequency, and every other instance of the job is built without it. Leave it empty and the event applies to every instance.

The picker offers the job's frequencies, live. The options come from the job's own Frequencies tab as you edit it, so adding or removing a frequency there is reflected immediately. A frequency the job doesn't run on is never offered, because an event scoped to one could never fire.

It is offered in definition scope only. Open a job instance and there is no picker: an instance is already one frequency, and its events were filtered to that frequency when it was built, so a choice there would change nothing. A stored value round-trips untouched.

Removing a frequency flags the events scoped to it

If you remove a frequency on the Frequencies tab while an event is still scoped to it, the event's Frequency picker stays visible, keeps showing the stale name, and reports "<the frequency>" is not one of this job's frequencies, so this event will never fire. Save refuses it until you pick a frequency the job has, or clear the scope.

It is flagged rather than cleared for you, because clearing it would silently widen the event to every frequency — a different event from the one you authored. Earlier builds accepted the stale scope and the event was saved to fire on instances that are never built.

A comma in a parameter is shown on the field

An event command separates its fields on commas and has no way to escape one, so a comma is refused in any field except a trailing list. Typing one now keeps the character, reports the message on the offending field, and leaves the generated command empty — which keeps Save disabled. The save message names the field too (Event 2: remove the comma from Schedule Name) rather than telling you to choose an event you have already chosen.

A comma inside a property token is fine: it is an argument to the token, resolved before the line is split. A stored event whose command was built elsewhere — Code view, the API, or a token holding a comma — still fires and does not block an unrelated save.

A command can carry property tokens. Write [[$JOB NAME]] or [[MyProperty]] anywhere in the command and it is resolved as the event fires, from the job's own record — so [[$JOB STATUS]] reports the status that fired the event, not the one assumed when the job started. If a token can't be resolved the event still fires and that field keeps the text as you wrote it. See When tokens are resolved for the names available and how encrypted properties are handled.

When each trigger is evaluated​

The two trigger types are checked at different points in a job's life, which is why a status event can fire mid-run but an exit-description event never does.

  • Job status events are checked on every status change, so they can fire while the job is still running (for example on LateToFinish).
  • Exit description events are checked only when the job finishes. Until then the job has no termination description to compare against.

Job status values​

FinishedOk · Failed · Fixed · Skipped · UnderReview · StartAttempted · StillAttemptingStart · LateToStart · LateToFinish · MissedLatestStartTime · exceededMaxRuntime

Failed also covers a job an operator marked failed, and a job that failed during initialization. FinishedOk likewise covers a job an operator marked finished OK.

exceededMaxRuntime is the odd one out — it is not a job status at all. See below.

exceededMaxRuntime is a derived condition, not a status​

exceededMaxRuntime sits in the Job status list in the editor, but it is the one entry there that is not a status. A job that runs past its Max Run Time is labelled rather than transitioned, so this trigger is matched by name and fires on the overrun itself.

It now fires. In earlier builds you could configure it, save it, and get silence forever — nothing in the platform compared a running job's elapsed time against its limit. What to know when you use it:

  • It fires while the job is still running, once per run, and the job is not stopped. A $JOB STATUS token in the command therefore renders the job's real status — JOB_RUNNING — not the condition that fired the event.
  • It is the opt-in way to kill an overrunning job. Attach a $JOB:KILL command to it. The platform never kills the job on its own.
  • It does not fire on the job's start, and it does not fire again when the job later finishes.

See Exceeding Max Run Time.

Triggers that do not fire yet​

One of the choices above saves correctly but never runs its command in the current release. It is listed here because you can select it in the job editor — not because it works.

SettingWhat happens today
Completion Expression triggerThe event is stored and validated, but skipped at run time. An expression evaluator now exists — it is what an expression dependency resolves through — but this trigger has not been connected to it. The command never runs.

To alert on a job that runs too long you have two working choices: an exceededMaxRuntime event, which needs only a Max Run Time on the job; or a LateToFinish status event, which needs the job to have both a planned end time and a late-finish threshold set — the job moves to LateToFinish once that many minutes have passed beyond the planned end.

Exit-description events​

EqualTo · NotEqualTo · GreaterThan · GreaterThanOrEqualTo · LessThan · LessThanOrEqualTo · Contains · Range (uses comparisonValue + comparisonEndRange)

What is actually compared​

The value on the left of the comparison is the job's termination description — the text a job finishes with — not its exit code. The two are separate fields, and this trigger only ever reads the description.

That matters more than it sounds, because of how the comparison then works:

  • The comparison is numeric only if all three values are whole numbers — the termination description and both bounds you set. If any of them is not, every operator falls back to a text comparison, including GreaterThan, LessThan and Range.
  • A job that finished OK has an empty description, and a job that failed usually has an error message. Neither is a number.

So on a job whose description is text, GreaterThan 4 does not mean "greater than four" — it compares as text, where "10" sorts below "9". Set a numeric comparison only where you know something writes a numeric termination description.

Good to know

A legacy job is one place that does. A Windows, UNIX/Linux or SQL legacy LSAM job that reports an exit code carries that code as its termination description, whether it finished or failed — so a numeric comparison is meaningful on those, and this is the trigger to use to key off a particular code.

This is also why such an event may be firing for you now when it never did before. Until recently a legacy job's description was blank on success and the text Job failed on failure, so no exit-description trigger fired on one, including an EqualTo 0. A job whose outcome exit criteria decided now carries its exit code too — the exit-criteria line used to overwrite it, which is why a trigger written for a particular code stayed silent on exactly the jobs most likely to have one. One case still carries text rather than a number: a failure that produced no exit code at all. SMAFT file-transfer and IBM i jobs are not included.

Text comparison rules​

When the comparison falls back to text:

  • it is case-insensitive — ABORTED and aborted match;
  • accents are significant;
  • trailing spaces are ignored, so "ABORTED " equals "ABORTED".

Two operators have their own rules:

OperatorRule
ContainsNever numeric. Always a case-insensitive substring search, whatever the values look like.
RangeIf you leave the end of the range unset it is treated as 0, which usually makes the range empty and the event never fire. Always set both bounds.

A job with no termination description at all is compared as an empty string — the event is still evaluated, not skipped.

Good to know
  • An event firing is expected behavior, not an error — e.g. a Failed-status event that sends an alert is the system working as designed.
  • If an expected event didn't fire, check the trigger configuration first: the status/exit comparison may not have matched, or the event's frequency may have excluded the run.
  • Events run a command — what that command does is defined by the command itself; the event only decides when it fires.

Workflow completion events​

Everything above is a job event. A workflow can also carry events of its own, which fire when the workflow completes rather than on any one job's outcome. They live on the Event Trigger tab of the workflow set-up panel, and they are the place to put the one thing that should happen once the whole run is done — build tomorrow's schedule, release a downstream workflow, send a single all-clear.

Each event is a card with an Event to Fire picker and a pencil that opens the full parameter form. Cards can be dragged into order, and that order is the order they fire in. Only event types the platform can actually apply are offered; a card holding a type that is no longer offered still shows the type it was saved with rather than reading as blank.

A workflow event has no trigger condition. Unlike a job event there is no status or comparison to set — a completion event fires on completion, which is why the tab asks only what to fire and not when.

The events are frozen onto the run when the workflow is built, so editing them changes the next build rather than a run already in progress.

An event with nothing to fire is caught before you commit

A card added with Add Event Trigger, or a job event added with Add New Event, carries no event until you pick one. Because the workflow editor's autosave only writes a local draft, the first thing that ever looked at such a card used to be Create Version — which refused it with a schema error naming neither the card nor the job.

Both are now reported where you can act on them. The workflow's validation names the card (Completion event 2: choose the event to fire) and the job's names the job and the event (Job 'X': event 2 has no event to fire), the type picker on the card itself says Choose the event to fire, and the job editor refuses the save rather than storing a blank. No stored workflow newly fails: an empty event was never valid to commit.

Input placeholders belong to Self Service, not to a workflow

The event parameter form is shared with the Self Service portal, where a parameter can carry a ${…} placeholder filled in from the requester's form. A workflow has no requester and no form, so nothing would ever fill one in. Those hints — the ${inputId} note, the field hint and the input and system-variable chips — are therefore not shown on a workflow's Event Trigger tab. Use a property token for a value the tenant already knows.