MDL Common Errors Cheatsheet

SkillDev tools

Gives your agent quick fixes for common MDL syntax errors reported by mxcli check.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the MDL Common Errors Cheatsheet skill

About this capability

Quick fixes for the MDL syntax errors that come up most: undeclared variables, wrong retrieve source, list operations, expression mistakes. Use when `mxcli check` reports an error and you want the fix rather than the reference.

What this skill tells your AI

The instructions your AI receives, as published by mendixlabs/mxcli in .claude/skills/mendix/cheatsheet-errors/SKILL.md and read by ahel’s review.

Quick fixes for common MDL syntax errors.

Variable Errors

"Variable 'X' is not declared"

Problem: Using SET on a variable that wasn't declared.

-- WRONG
if $value > 10 then
  set $IsValid = false;  -- ERROR: $IsValid not declared
end if;

Fix: Add DECLARE before SET.

-- CORRECT
declare $IsValid boolean = true;
if $value > 10 then
  set $IsValid = false;
end if;

"Selected type is not allowed" (CE0053)

Problem: Declaring an object (entity) or list variable. A declare maps to a Create Variable activity, which only accepts primitives (String/Integer/Long/Decimal/Boolean/DateTime/Enumeration). Declaring an object or list is rejected (CE0053/CE0038, plus CE7247 on any later set) — bare or initialized. The as keyword is also a parse error in mxcli. mxcli check flags an object declare as MDL043 and a list declare as MDL040.

-- WRONG: declaring an object — there is no "empty object variable" (MDL043)
declare $Product Module.Product = empty;
declare $Product as Module.Product;         -- AS is also a parse error
-- WRONG: declaring a list (MDL040)
declare $Products list of Module.Product = empty;

Fix: Objects and lists can't be declared — get them from a source that produces one.

-- object: a microflow parameter, a retrieve, a create, or a loop iterator
retrieve $Product from Module.Product where Code = $Code limit 1;  -- retrieve
$Product = create Module.Product (Name = $Name);                   -- create
-- or: create microflow M.Save ($Product: Module.Product) ... / loop $Product in $Products ...

-- list: a parameter, a retrieve, or a create list
$Products = create list of Module.Product;   -- empty list to accumulate into
retrieve $Products from Module.Product where ...;  -- or populate from the database

Expression Errors

"Error in expression" (CE0117)

Problem 1: Using unqualified association name in XPath.

-- WRONG: Missing module qualification
set $Name = $Order/Customer/Name;

Fix: Use fully qualified association name.

-- CORRECT: Module.AssociationName
set $Name = $Order/Shop.Order_Customer/Name;

Problem 2: Using not without parentheses — Mendix requires not(expr) form.

-- WRONG: bare not rejected by Studio Pro
if not $IsActive then ...
if not contains($Name, 'demo') then ...

Fix: Always wrap the negated expression in parentheses.

-- CORRECT: not(expr)
if not($IsActive) then ...
if not(contains($Name, 'demo')) then ...

mxcli enforces this at parse time — not expr without parens is a syntax error.

"Type mismatch" in enum comparison

Problem: Comparing enumeration with string literal.

-- WRONG: String literal instead of enum value
if $task/status = 'Completed' then

Fix: Use qualified enumeration value.

-- CORRECT: Module.Enumeration.Value
if $task/status = Module.TaskStatus.Completed then

Control Flow Errors

"Activity cannot be the last object" (CE0105)

Problem: Missing RETURN statement.

-- WRONG: No RETURN
begin
  declare $Result boolean = true;
  log info 'Done';
  -- Missing RETURN!
end;

Fix: Add RETURN statement.

-- CORRECT
begin
  declare $Result boolean = true;
  log info 'Done';
  return $Result;
end;

"Action activity is unreachable" (CE0104)

Problem: Code after RETURN statement.

-- WRONG: Code after RETURN
if $value < 0 then
  return false;
  log info 'Negative';  -- Unreachable!
end if;

Fix: Move code before RETURN.

-- CORRECT
if $value < 0 then
  log info 'Negative';
  return false;
end if;

Syntax Errors

Division operator

-- WRONG: Using / for division
set $average = $Total / $count;

-- CORRECT: Use 'div' keyword
set $average = $Total div $count;

Missing END IF / END LOOP

-- WRONG: Missing END IF
if $value > 0 then
  set $Positive = true;
-- Missing END IF!

-- CORRECT
if $value > 0 then
  set $Positive = true;
end if;

Missing semicolons

-- WRONG: Missing semicolon
declare $count integer = 0
set $count = 1

-- CORRECT
declare $count integer = 0;
set $count = 1;

Reference Errors

"Module not found"

Problem: Using non-existent module name.

Fix: Check module exists with show modules.

"Entity not found"

Problem: Using non-existent entity name.

Fix:

  1. Check entity exists: show entities in ModuleName
  2. Use fully qualified name: Module.EntityName

"Microflow not found"

Problem: Calling non-existent microflow.

Fix:

  1. Check microflow exists: show microflows in ModuleName
  2. Use fully qualified name: Module.MicroflowName

"page not found" for a page the script creates further down (MDL-PAGE01)

Problem: A widget action targets a page created by a LATER statement in the same script. Page references resolve in statement order, and exec is not transactional — the statements before the failure are already written.

Fix:

  1. Move the create page for the target above the page that links to it.
  2. If two pages link to each other, no ordering works: create one without the linking widget, then add it with alter page ... insert.
  3. Commit before executing a large script — recovery from a partial run is git checkout -- App.mpr mprcontents/.

"not found" for anything else the script creates further down (MDL-ORDER01)

Problem: Same shape as MDL-PAGE01, for the other references the executor resolves when it writes the referring document — a flow's parameter or return type, an entity attribute's enumeration, an association endpoint, a call microflow/call nanoflow target, or a grant subject. check used to pass these and exec then failed partway through.

Fix: Move the create for the named document above the statement that uses it. Statements have no dependency order beyond this, so grouping entities and enumerations at the top of a script avoids it entirely.

Not every forward reference is an error. These execute fine with the definition afterwards, and are deliberately not flagged: an entity's extends generalization, call java action, retrieve ... from, and create <entity> inside a microflow body.

One case check cannot predict: if the document is created later by create or modify, exec still fails when the project does not already have it — but the script alone cannot say whether it does, so no error is reported. Run with -p for the fullest coverage.

Studio Pro Error Code Reference

CodeMessageCommon Cause
CE0053Selected type is not allowedDeclared an object/list variable — get it from a parameter/retrieve/create/loop (MDL043 objects, MDL040 lists)
CE0104Action activity is unreachableCode after RETURN
CE0105Must end with end eventMissing RETURN
CE0117Error in expressionUnqualified association path
CE1571No argument selected for parameterA microflow/nanoflow call with a parameter nothing fills — as a datasource: or an action:. Give it an argument (action: nanoflow M.NF($P = $value)), or nest the widget in a data container of the parameter's type. check -p reports both
CE1571…in a control barA control bar is not row-scoped, so the grid's row does not fill it: pass the grid's selection ($dgOrders, with Selection: set) or move the widget into a column. $currentObject there is MDL-BUTTON01
CE1834The 'Page' property is requiredWorkflow user task without a page — check flags MDL-WF01
CE1876Single outcome must not contain activitiesSingle-outcome user task with a nested activity flow — check flags MDL-WF02
CE6686Outcomes do not match the configured expression/microflowAn enumeration decision or call-microflow activity missing the empty outcome ('' -> { }) or an enumeration value — check flags the missing empty one as MDL-WF06
CW0094Variable never usedUnused parameter/variable

Quick Validation Checklist

Before executing MDL:

  • No object or list is declared — objects come from a parameter/retrieve/create/loop (MDL043); lists from a parameter/retrieve/create list (MDL040)
  • All SET targets have prior DECLARE
  • Association paths are qualified: $var/Module.Assoc/attr
  • Enum comparisons use Module.Enum.Value
  • Every flow path ends with RETURN
  • Division uses div not /
  • All statements end with ;
  • IF/LOOP properly closed with END IF/END LOOP

Signals

GitHub stars
122
Forks
49
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
cheatsheet-errors
Source
github.com/mendixlabs/mxcli