Skip to content

LOCK/UNLOCK WORKFLOW ALL writes an activity that cannot build (CE1825) #870

Description

@ako

lock workflow all; and unlock workflow all; parse, pass mxcli check, and execute successfully — then mxbuild rejects the result. The MDL form appears to have no valid representation in the model at all, so this is a question about what the syntax should mean rather than a defect with one obvious fix.

Found while adding reader coverage for the workflow call actions, which deliberately left this alone.

Reproduction

create module W;
create microflow W.MF_LockAll ()
begin
  lock workflow all;
  unlock workflow all;
end;
$ mxcli exec t.mdl -p AppWF.mpr
Created microflow: W.MF_LockAll

$ mx check -p AppWF.mpr
[error] [CE1825] "The 'Workflow' property is required." at Lock workflow activity 'Lock workflow'
[error] [CE1825] "The 'Workflow' property is required." at Unlock workflow activity 'Unlock workflow'
The app contains: 2 errors.

Mendix 11.13.0. Both engines — identical output with --engine legacy, so this is not modelsdk-specific.

Control

The variable form is fine, which isolates the failure to all:

statement mx check
lock workflow $WfDef / unlock workflow $WfDef 0 errors
lock workflow all / unlock workflow all 2 errors (CE1825)

Why the obvious fix doesn't work

The writer omits WorkflowSelection when the "all" flag is set:

// mdl/backend/modelsdk/microflow_workflow_write.go:77
addBool(g, "PauseAllWorkflows", a.PauseAllWorkflows)
if !a.PauseAllWorkflows {
    addPart(g, "WorkflowSelection", workflowSelectionToGen(a.Workflow, a.WorkflowVariable))
}

(sdk/mpr/writer_microflow_workflow.go:156 has the same guard.)

I tried always emitting the selection. It still fails with CE1825 — because in the all form there is no workflow to name, so workflowSelectionToGen("", "") produces an object selection with an empty variable, which is just as unset.

What the metamodel says

From the Mendix Model SDK (mendixmodelsdk, gen/workflows.d.ts), WorkflowDefinitionSelection has exactly two concrete subclasses:

  • WorkflowDefinitionNameSelection — a workflow qualified name
  • WorkflowDefinitionObjectSelection — a WorkflowDefinition variable

There is no all-definitions variant. On LockWorkflowAction, workflow was deleted in 10.0.0, workflowSelection was introduced in 10.0.0, and pauseAllWorkflows defaults to true.

That combination suggests pauseAllWorkflows does not mean "all workflow definitions" at all — more likely "all instances of the selected definition". If so, a lock/unlock always needs a specific definition, and MDL's all keyword is expressing something the model cannot represent.

The decision to make

mdl/grammar/domains/MDLMicroflow.g4:472 currently allows:

lockWorkflowStatement
    : LOCK WORKFLOW (VARIABLE | ALL) onErrorClause?

Options, roughly in order of my confidence:

  1. Drop the ALL alternative. If the model cannot express it, accepting it only produces unbuildable projects. Existing scripts using it are already broken.
  2. Require a workflow with the flag — e.g. lock workflow $WfDef all / lock workflow W.Approve all, mapping to a selection plus PauseAllWorkflows: true. This matches the "all instances of that definition" reading, but I have not confirmed that reading against Studio Pro.
  3. Refuse at author time (an MDL rule, like MDL058), keeping the grammar but rejecting before the write.

Settling between (1) and (2) needs one Studio Pro data point: create a Lock workflow activity with the "pause all" checkbox ticked and see whether it still stores a WorkflowSelection. That would confirm what the flag means and whether option 2 is real.

Scope note

Whatever is chosen, it should also cover sdk/mpr (legacy), since both engines emit the same shape.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions