Skip to main content

How actions work

Actions are the side effects of a workflow. You define them once in the definition’s Actions tab, then reference them from the Actions tab of a node or of a transition. Chains run in order; if an action fails, the instance’s variables roll back to their node-entry state and the instance routes to the error node (or is marked Failed). A few conventions apply across the catalog:
  • Value parameters accept expressions. Anything marked expr below can be a literal, contain {{ references }}, or be switched to expression mode and computed with a formula like $instance.retries + 1.
  • Actions target the anchor by default. Keyword, document and Caseflow actions accept an optional DocumentId / ObjectId parameter; leave it empty to act on the workflow’s own document or object, or supply an expression (for example an ID read from a keyword) to act on a related document or object. The designer offers these actions in document and Caseflow workflows alike. A workflow of the other kind has no document or object of its own to fall back on, so set the parameter there — without it the action fails. The keyword and attribute actions also have a TargetDocumentTypeId / TargetClassId setting: it tells the designer which type the target is, so its pickers offer the right keywords or attributes, and the engine ignores it when the action runs. TargetDocumentTypeId shows once DocumentId points at a related document. TargetClassId shows once ObjectId points at a related object in a Caseflow workflow, and always in any other workflow, which has no object of its own. You pick the target class by application and then class, as described under Caseflow actions. Document.Reindex is the exception: its TargetDocumentTypeId is the document type the document is reindexed to, and the action requires it even when the designer hides the field — see Document actions.
  • Some actions capture output. Actions with an IntoVariable parameter store their result as an instance variable for later steps to read as instance.<name>.

Keyword actions

Document actions

The designer treats Document.Reindex’s TargetDocumentTypeId like the keyword actions’ target type and shows it only once DocumentId points at another document, so Validate reports it missing when the action reindexes the workflow’s own document. Set it in the JSON view instead: add "targetDocumentTypeId" with the document type’s ID to the action’s params, then choose Apply changes. Under Settings → Admin Settings → Documents → Document types, each type’s group and ID — # and a number — are shown below its name. Opening that page takes document-structure.view.

Caseflow actions

The identifiers below are the ones the designer’s action picker shows and a definition stores. All four work in a document workflow too. Caseflow.CreateObject never acts on the workflow’s anchor, so it needs no ObjectId — as in Ask before creating a case object. The other three need an ObjectId there, for example the ID Caseflow.CreateObject stored in its IntoVariable, or one read from a keyword. ClassId and TargetClassId are picked in two steps: first a Caseflow application, then one of its classes. This works the same in document and Caseflow workflows, and the class can come from any application, not only the workflow’s own. A new field starts on the workflow’s own application when it has one. Choosing another application clears the class. The definition stores only the class’s ID, so a class ID typed by hand still works, for example one entered in the JSON view or saved in an older definition: the field opens it under its own application. If the designer cannot offer the class from its lists, the field becomes a plain input for the class’s ID, with a hint that says why. That happens when Caseflow applications or classes cannot be loaded or none are available to you, when the stored value is not a class ID, when the class does not exist or is not available to you, and when it belongs to an application you cannot see. The same input keeps a template such as {{instance.classId}} as text. To check a class’s ID, open Settings → Admin Settings → Caseflow → Applications & classes, where the class list shows each class’s ID as # and a number below its name. Opening that page takes caseflow-configuration.view. An AttributeId field lists the attributes of one class:
  • In Caseflow.CreateObject, the class in its ClassId.
  • In a Caseflow workflow, the workflow’s own class while ObjectId points at the workflow’s object, and the TargetClassId class once it points at a related object.
  • In any other workflow, the TargetClassId class.
Until that class is set to a fixed class (not a template), the attribute field is a plain input, with a hint that names the field to set first.

Variable actions

Email

Never hardcode SMTP credentials in the definition. Reference configuration instead: {{ env.smtp_host }} for the host and user, and {{ secrets.smtp_password }} for the password. Secrets are encrypted at rest and never written to instance history.
The email Body field uses the template editor with {{ }} autocomplete, so you can mix prose with references:

Workflow control

Show a result to the person who started the run

When someone starts a workflow from a workflow document action, Workflow.SetMessage tells them what happened. The designer lists it under Workflow in every kind of workflow, but only a document workflow can be started from a document action, so that is where the message is seen.
  • Only the person who started the run sees it. It appears only for runs started from a document action. Other runs record the message in their history and show it to no one. With workflow-engine.view, you can read it in the instance history, under the action that set it, with its level, title, text, and any document it names.
  • The last message wins. A message set before a long step, such as a background Script.Run, is shown as progress text while the run waits, and a later message replaces it.
  • Shown while the person is following the run. The message reaches them in the answer to their click, or while the run waits on a Join for a background script or a batch. A run is followed for a little over half an hour, long enough for one background script to reach its 30-minute limit; after that, the person is told it is taking longer than expected and to check the document later. A run that stops to wait for a task or a timer tells them it has started, showing any message set so far, and is not followed after that. A message set once following has stopped is recorded in the history only. So is a message set after they close the browser tab, unless they choose the action again while the run is still going; reloading the page keeps the run followed. When the work can take longer, such as two background scripts in a row or a batch over many documents, say so in the progress message, because the final message may not reach them.
  • Plain text. Markup is shown as typed and links are not made clickable. Line breaks in the text are kept, and a longer title or text is shortened and ends in ….
  • Failures hide success messages. A run that failed or was stopped before it finished, or one that took its error path after the message was set, does not show success or info messages; warning and error messages are always shown. Set the failure message on the error node, at level error. It can include {{instance._error.message}}, the failing step’s technical reason.
  • It is not a variable. The message is recorded in the instance history, so later steps cannot read it back, and setting a variable cannot change what the person sees.
  • No secrets. Publishing refuses a Workflow.SetMessage whose parameters reference $secrets.*, because the person would see the value.
  • Its level, title, and text never fail the run. A level that resolves to something other than the four values shows as info. Only a DocumentId that does not resolve to a whole number fails the action, which sends the run down its error path.
After a background script finishes, the result can take up to about a minute to appear. Confirm, run a background script, show the result puts these together.

Scripts

To pass a structured input, write an object literal in the formula editor:
See Script Engine for authoring, publication, bindings, and execution logs. Script.Run resolves the published script by slug; publishing a workflow does not freeze that script’s source.

Run a script in the background

A script that needs minutes rather than seconds, such as splitting or merging PDFs or a nightly sweep, can run in the background for up to 30 minutes. Configure the Script.Run action like this:
  • Turn on RunInBackground and set TimeoutMinutes (1–30, default 30).
  • Set IntoVariable. It is required, because the node waits on it.
  • Run the action from the Actions tab of the node that waits for it, not from a transition.
  • Give that node a Join transition whose job is the same variable, for example $instance.merge.
The action itself only records the run. The run starts once the step has been saved, and the node parks on the Join until the script has finished. When the Join fires, the script’s output is under .output, for example $instance.merge.output.fileName. A synchronous run puts the output straight into the variable instead.
  • Failures take the error path. A run that fails, times out, is cancelled or is lost does not fire the Join. The node routes to its error node, or the workflow’s, with the Script Engine’s reason in $instance._error.message.
  • At most once. A run the Script Engine loses to a restart or deployment ends as lost and is not repeated, because its effects may already have happened. Replaying the failed instance starts a new run.
  • Leaving the node cancels the run. If a timer fallback on the same node fires first, or the instance ends, the run is cancelled. Set such a timer comfortably above TimeoutMinutes.
  • Different identity. A background script calls Insight as the Script Engine’s service account, not the Workflow Engine’s. Grant that account’s user the document types and privileges the script uses, for example the Keyword Sets privilege to write autofill entries.
The designer checks these rules when you publish: a background run without a result variable, one run from a transition, or one whose node has no matching Join is rejected. Steps after the Join run as the system, so {{identity.username}} there renders system rather than the person who started the run. For that person, read the run’s owner: {{owner.username}} in templates or $owner.username in formulas, which is the same in every step.

References & expressions

The formula language and reference catalog used in workflow guards, trigger filters, action parameters, and body templates.