Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Activity Types

Workflow activities are the building blocks of a workflow definition. Each activity type serves a different purpose, from waiting for user input to calling microflows or branching execution.

User Task

A user task pauses the workflow until a user completes it. Each outcome resumes the workflow down a different path.

USER TASK <name> '<caption>'
  [PAGE <Module>.<Page>]
  [TARGETING MICROFLOW <Module>.<Microflow>]
  [ON CREATED MICROFLOW <Module>.<Microflow>]
  OUTCOMES '<outcome>' { <activities> } ['<outcome>' { <activities> }] ...;
ElementDescription
<name>Internal activity name
<caption>Display label shown to users
PAGEThe page opened when the user acts on the task
TARGETING MICROFLOWMicroflow that determines which users see the task
ON CREATED MICROFLOWMicroflow run when the task is created — for example to assign it. It takes exactly System.WorkflowUserTask and the workflow’s context entity, in either order (else CE6683), and returns nothing (else CE5012)
OUTCOMESNamed outcomes, each with a block of follow-up activities

Example:

USER TASK ReviewTask 'Review the request'
  PAGE Approval.ReviewPage
  TARGETING MICROFLOW Approval.ACT_GetReviewers
  ON CREATED MICROFLOW Approval.ACT_AssignReviewer
  OUTCOMES 'Approve' {
    CALL MICROFLOW Approval.ACT_Approve;
  } 'Reject' {
    CALL MICROFLOW Approval.ACT_Reject;
    END WORKFLOW;
  };

Multi-User Task

A multi-user task gives the same task to several users and combines their outcomes into one. Three clauses, before OUTCOMES, say how:

MULTI USER TASK <name> '<caption>'
  PAGE <Module>.<Page>
  [PARTICIPANTS ALL | <n> | <n> PERCENT]
  [DECIDE BY <rule>]
  [AWAIT ALL USERS]
  OUTCOMES '<outcome>' { <activities> } ...;
RuleCompletes whenNeeds
CONSENSUSeveryone chose the same outcomeFALLBACK '<outcome>'
MAJORITY MORE THAN HALFmore than half chose one outcomeFALLBACK '<outcome>'
MAJORITY MOST CHOSENone outcome was chosen mostFALLBACK '<outcome>'
THRESHOLD <n> PERCENT / <n> VOTESan outcome reaches the thresholdFALLBACK '<outcome>'
VETO '<outcome>'anyone chooses the veto outcome—
MICROFLOW <Module>.<Name>the microflow returns the outcome (String)—

Example:

MULTI USER TASK Vote 'Vote on the request'
  PAGE HR.VotePage
  PARTICIPANTS 80 PERCENT
  DECIDE BY THRESHOLD 60 PERCENT FALLBACK 'Reject'
  AWAIT ALL USERS
  OUTCOMES 'Approve' { } 'Reject' { };

Omitted, the task needs all participants, decides by consensus falling back to its first outcome, and does not wait for everyone. The fallback is required for consensus, majority and threshold, and the build does not check threshold or participant numbers against each other — THRESHOLD 5 VOTES with three users builds and never completes.

Call Microflow

Execute a microflow as part of the workflow. Optionally specify a caption and outcomes:

CALL MICROFLOW <Module>.<Name> [(<Param> = <expression>, ...)] [CAPTION '<text>']
  [OUTCOMES '<outcome>' { <activities> } ...];

Example:

CALL MICROFLOW HR.ACT_SendNotification CAPTION 'Notify the applicant';
CALL MICROFLOW HR.ACT_Escalate(Request = $WorkflowContext) CAPTION 'Escalate';

Arguments are bound like every other call in MDL: Param = expression right after the callee, the expression written bare. The older spelling after the caption, WITH (Param = '<expression>') with the expression inside a string, still parses with the same meaning but is deprecated (MDL-DEPR008); mxcli fmt --upgrade rewrites it.

CAPTION '…' sets the caption Studio Pro shows on the activity, on every workflow activity. It used to be spelt COMMENT '…', which still parses as a deprecated alias (MDL-DEPR104) — it was never a comment.

AI Agent Task

A step that runs an AI agent (Mendix 11.9 or later). It is written like CALL MICROFLOW with AGENT added, and takes the same name, caption, parameter mappings, outcomes and boundary events. The microflow is where the agent is invoked — build agents with the Studio Pro Agent Editor, or CREATE AGENT.

CALL AGENT MICROFLOW <Module>.<Name> [(<Param> = <expression>, ...)] [AS <name>] [CAPTION '<text>']
  [OUTCOMES <true|false|'Module.Enum.Value'|''> -> { <activities> } ...];

Example — branch on the agent’s answer:

CALL AGENT MICROFLOW HR.ACT_ClassifyRequest(Request = $WorkflowContext) AS aiAgentTask1
  CAPTION 'Classify the request'
  OUTCOMES true -> {
    USER TASK Expedite 'Expedite the request' PAGE HR.TaskPage OUTCOMES 'Done' { };
  } false -> { };

The microflow must take at least one parameter — usually the workflow’s context object — or the build fails with CE1590. Return Boolean or an enumeration to branch with OUTCOMES; return nothing for a single path.

Call Workflow

Start a sub-workflow:

CALL WORKFLOW <Module>.<Name> [(<Param> = <expression>, ...)] [CAPTION '<text>'];

Example:

CALL WORKFLOW HR.BackgroundCheck CAPTION 'Run background check sub-process';

Decision

Branch the workflow based on a condition. The condition is a bare expression, Boolean or enumeration; each outcome contains a block of activities:

DECISION [<name>] <expression> [COMMENT '<caption>']
  OUTCOMES TRUE -> { <activities> } FALSE -> { <activities> };

Example:

DECISION $WorkflowContext/Total > 1000 CAPTION 'Order value over $1000?'
  OUTCOMES TRUE -> {
    USER TASK ManagerApproval 'Manager must approve'
      PAGE Shop.ApprovalPage
      OUTCOMES 'Approved' { } 'Rejected' { END WORKFLOW; };
  } FALSE -> { };

An enumeration decision has one outcome per qualified enumeration value, plus '' for “none of the above”. The expression used to be written in a string (DECISION '$WorkflowContext/Total > 1000'); that form still parses and warns MDL-DEPR080, and mxcli fmt --upgrade rewrites it.

Parallel Split

Execute multiple paths concurrently. The workflow continues after all paths complete:

PARALLEL SPLIT
  PATH 1 { <activities> }
  PATH 2 { <activities> }
  [PATH 3 { <activities> }] ...;

Example:

PARALLEL SPLIT
  PATH 1 {
    USER TASK LegalReview 'Legal review'
      PAGE Legal.ReviewPage
      OUTCOMES 'Approved' { };
  }
  PATH 2 {
    USER TASK FinanceReview 'Finance review'
      PAGE Finance.ReviewPage
      OUTCOMES 'Approved' { };
  };

Jump To

Jump to a named activity elsewhere in the workflow (creates a loop or skip):

JUMP TO <activity-name>;

Example:

JUMP TO ReviewTask;

Wait for Timer

Pause the workflow until a timer expression evaluates:

WAIT FOR TIMER [<name>] [<expression>] [COMMENT '<caption>'];

Example:

WAIT FOR TIMER addDays([%CurrentDateTime%], 3);

Wait for Notification

Pause the workflow until an external notification resumes it:

WAIT FOR NOTIFICATION;

Notification

An intermediate notification event (Mendix 11.11+): the point a NOTIFY WORKFLOW action targets by name.

NOTIFICATION [<name>] [CAPTION '<caption>'];

A notification boundary event attaches the same trigger to a user task, call microflow or wait. It takes a name instead of a timer delay:

USER TASK Review 'Review'
  PAGE HR.ReviewPage
  OUTCOMES 'Approve' { } 'Reject' { }
  BOUNDARY EVENT INTERRUPTING NOTIFICATION Withdrawn 'Request withdrawn' {
    END WORKFLOW;
  };

An activity may carry only one interrupting boundary event (CE6697). ALTER WORKFLOW … { INSERT INTO <activity> { BOUNDARY EVENT … } } cannot add a notification boundary event yet.

A microflow reaches any of these with NOTIFY WORKFLOW, naming the element:

$Notified = NOTIFY WORKFLOW $Workflow TARGET HR.Leave.Withdrawn;

The target is required — a notify without one fails the build (CE0166). It may name a notification activity, a notification boundary event, a wait for notification, or the start of a notification-started event sub-process; mxcli works out which, and refuses anything a notification cannot reach.

Event Sub-Processes

A flow outside the main flow, started by its own start event while the workflow runs. Written after the main body, before END WORKFLOW:

EVENT SUBPROCESS <name> ['<caption>']
  ON (INTERRUPTING | NON INTERRUPTING) NOTIFICATION [<start>] ['<start caption>']
  { <activities> };

EVENT SUBPROCESS <name> ['<caption>']
  ON (INTERRUPTING | NON INTERRUPTING) TIMER <first-execution-time> [AS <start>] [CAPTION '<start caption>']
  { <activities> };

Example:

EVENT SUBPROCESS ESP_Cancel 'Cancel request'
  ON INTERRUPTING NOTIFICATION espCancelStart 'Cancel received' {
  CALL MICROFLOW HR.ACT_LogCancel;
};
  • Interrupting cancels every active path before the sub-process runs; non-interrupting runs alongside the main flow.
  • The body’s End is implicit, as in the main flow. A body that already ends (in END WORKFLOW, a JUMP TO, or branches that all end) gets none.
  • A JUMP TO must stay inside its own sub-process (CE6682).
  • A timer start needs its expression (CE0126).
  • Versions: notification starts need Mendix 11.8+, timer starts 11.13+.

End

Terminate the current workflow path:

END;

Typically used inside an outcome block to stop the workflow after a rejection or cancellation.

Notes (annotations)

Studio Pro’s notes attach to an activity. Write one as @annotation '…' on the line before the activity, as in a microflow; an event sub-process takes it before EVENT SUBPROCESS, and the note on the workflow itself is the header clause ANNOTATION '…':

CREATE WORKFLOW Module.Approve
  PARAMETER $WorkflowContext: Module.Request
  ANNOTATION 'Started from the request form'
BEGIN
  @annotation 'Escalates after two days'
  USER TASK Review 'Review' PAGE Module.Review_Task OUTCOMES 'Done' { };
END WORKFLOW;

An activity takes one note, and no other @ annotation. DESCRIBE WORKFLOW writes them the same way, so a replay keeps them. A standalone ANNOTATION '…'; statement in the body is refused (MDL-WF04): Mendix cannot load a note placed in the activity flow.

Summary Table

ActivityPurposePauses Workflow?
USER TASKWait for human actionYes
CALL MICROFLOWExecute server logicNo
CALL AGENT MICROFLOWRun an AI agent step (11.9+)No
CALL WORKFLOWStart sub-workflowDepends on sub-workflow
DECISIONBranch on conditionNo
PARALLEL SPLITConcurrent executionYes (waits for all paths)
JUMP TOGo to named activityNo
WAIT FOR TIMERDelay executionYes
WAIT FOR NOTIFICATIONWait for external signalYes
NOTIFICATIONIntermediate notification event (11.11+)Yes
EVENT SUBPROCESSFlow started by a notification or timer (11.8+)No (runs beside or replaces the main flow)
ENDTerminate pathN/A

See Also