Repository navigation
v0.26.0
[0.26.0] - 2026-10-11
Headline: Documents mxcli writes now survive Studio Pro's merge and diff: every element carries exactly the property names Studio Pro writes for the project's Mendix version. Before, a key mxcli left out, or wrote for a newer version, made a document unmergeable the first time Studio Pro saved it, although mx check, the build and the runtime stayed green. mxcli fix property-sets repairs projects an older mxcli wrote. Alongside it: a Claude Code companion mod with a Project pane, describe → exec round trips that keep loop back-edges, shared error handlers and page design properties, check -p resolving script sets and security references the way exec does, mxcli run --local as a background service, and a run of Windows fixes for the local dev loop. The language poster puts all of mxcli and MDL on one page.
Added
alter page/alter snippetadd and drop parameters (#1234) —add parameters $Order: M.Orderanddrop parameters $Order, besideadd variables/drop variables. Before,add parameterswas a parse error ("mismatched input 'parameters' expecting VARIABLES_KW") and the only route wascreate or replace page, which rebuilds every widget and loses whatdescribedoes not round-trip. The declaration is CREATE'sParams:rule, written by the same converters (so the 11.5+IsRequired/DefaultValuegate holds). A page with aUrlmust name the new parameter in it —set (Url: …)in the same statement — or exec refuses with the URL to use (mxbuild CE5601, measured on 11.12.1); a snippet parameter must be an entity (MDL087, at check time too); a drop is refused while a data source or expression still uses the parameter.mxcli git note— Studio Pro's commit metadata for commits made with git, and theteamserver-gitskill (#1337) — Studio Pro attaches a note underrefs/notes/mx_metadatato every commit (Mendix version, branch, and the model units the commit changed) and reads it to check a revision's version and show what it changed; a commit an agent made with git had none, Studio Pro 11.13 back-filled an"(unknown)"placeholder, and the user saw conflicts and changes the change pane did not show.mxcli git note -p app.mpr [--write]computes the note from the commit — the.mprunit index andmprcontentsat the commit and its parent — for the commits not yet pushed (or the ones named), keeps any note Studio Pro wrote (--forcereplaces it) and replaces placeholders. Measured against the 8 notes Studio Pro wrote on a Team Server repository's MPR v2 history: the header is identical on all 8 and the change list identical on every ordinary commit (Added/Modified/Deleted/Moved, a deleted module listed once,$ID-only re-serialisation not listed); on a version upgrade, which Studio Pro does and annotates itself, it lists more units than Studio Pro. The newteamserver-gitskill teaches the workflow: commit from Studio Pro when it is open, create branches on the Team Server (a local-only branch crashes Studio Pro 11.13 on open), pushrefs/notes/mx_metadatawith the branch before Studio Pro's background fetch discards it, and never merge, rebase or force-push model history with git.languages()in Starlark lint rules — the languages enabled in the project (#1306) — a rule had no way to tell which languages are enabled:strings()has a row for every stored translation, and a fresh en_US-only app already carries nl_NL texts, so enabling a language changed nothing a rule could see, andlanguages()failed to load withundefined: languages. It returns onelanguageper enabled language, from the project settings, withcode,is_defaultandcheck_completeness, so a per-language check (every page title translated into each enabled language) can filterstrings()to the enabled codes. It reads the project settings, not the catalog, so it needs no full catalog build; a failed settings read fails the rule instead of answering[].- A published REST service's authentication (#1331) —
create [or modify] published rest service M.Api (…, Authentication: (basic, session, microflow M.Authenticate))sets Studio Pro's Requires authentication and its methods:basic(username and password),session(active session),microflow M.F(custom);Authentication: noneis "Requires authentication: No". The methods are stored in the order written, which is how Studio Pro stores the ones ticked, anddescribeprints them in the stored order (it omitsnone). Left out,create or modifyandalterkeep the stored setting, as before.alter published rest service M.Api set ( Key: value, … )now takes create's property list (Path,Version,ServiceName,Authentication);set Key = '…'still works. The authentication microflow must returnSystem.Userand take only aSystem.HttpRequestand/orSystem.HttpResponse(Mendix: CE0334, CE0336, measured withmx checkon 11.14.0);execandcheck --referencesrefuse anything else as MDL-REST04. Executing thedescribeoutput of each of ako/TestApp's Studio Pro services writes nothing. send email— the built-in Send Email activity (Mendix 11.13+, beta) —send email ( From: …, To: …, Subject: 'Order {1}' with ({1} = …), Body: template '…', HtmlBody: template '…', Headers: ('X-Name': 'value'), Attachment: $Doc, Host: …, Port: …, SecurityType: ssl, CheckServerIdentity: true, ConnectionTimeout: 30000, Authentication: basic (Username: …, Password: …) ) [on error …];creates aMicroflows$SendEmailAction, which sends SMTP mail without the Email Connector module. The settings are one property list (ADR-0013), keyed by the metamodel's names; an unknown, repeated or misshapen key is an error, and so is a missing From, Host, Port or recipient (mxbuild: CE0166).describe microflowrenders the activity instead of-- Unsupported action: Microflows$SendEmailAction, and the description re-executes to the same activity.checktype-checks its expressions (E009: String addresses, host and credentials, Integer/Long port, String template parameters — what mxbuild reports as CE9528/CE0117), and warns on a server-identity check without SSL and on header names Studio Pro would refuse (MDL-EMAIL02/03). A 10.x–11.12 project is refused; a stored activity MDL cannot restate (authentication document, pre-11.13 message) still describes as unsupported rather than being rewritten smaller.mxcli syntax microflow.send-email. (#1315)mxcli playwright check— a text verdict for pages of a running app, in one call —mxcli playwright check /p/a /p/b -p app.mprloads each page in one headless browser and prints the verdictrun --page-checkprints (title, heading, rows, visible text, error banners, console errors) plus failed same-origin requests and the HTTP status, thenOK n page(s)orFAIL k of n page(s). Exit status 0 all passed, 1 a page failed (HTTP error, sign-in form or a 401 instead of the page, an error banner or error dialog, a console error, a failed request, a failed assertion), 2 the check could not run. It signs in when needed —--user/--password,--role R(the project's demo user with that user role), or with only-pa demo user — saves the session under.mxcli/playwright-check/, reuses it on the next check and renews it when the runtime has restarted.--assert-text,--assert-count 'SELECTOR>=N', and--screenshot out.png, which prints the path and never the image. It replaces the hand-written playwright-cli login/goto/sleep/eval/screenshot sequences that were about a sixth of the tool calls in a measured app-building session, each ending in a PNG read; thetest-appandverify-in-runtimeskills and/mendix:testnow route "check a page" to it.mxcli run --localruns as a background service —--detachstarts the warm loop in its own session and returns once the app serves (running: http://127.0.0.1:8080/ (pid N, watch, log .mxcli/run.log)), or prints the boot failure and the last log lines and exits 1.mxcli run statusprints one line (URL, uptime, last build and how it was applied, a pending change; a dead pid is reported as stopped).mxcli run waitblocks until the model as it is now has been applied —applied: build #3 via reload in 1.4s— or failed, with the CE codes; it is race-free (a change already applied when it starts is reported at once), somxcli exec x.mdl && mxcli run waitis one honest call;--readywaits for the boot.mxcli run stopshuts the run down and then sweeps its process session, so no orphaned runtimelauncher or mxbuild JVM is left, even from a run killed with-9.mxcli run restartstops and detaches again with the same arguments. Exit codes: 0 ok, 1 failed, 2 timeout, 3 not running, 4 starting. A second run for a project that already has one is refused. These replace thenohup/until grep/pkillloops that took about a quarter of all tool calls in measured agent sessions; the run-local and run-app skills and the generated CLAUDE.md now teach them.mxcli diag session-report— where an agent session's calls and tokens went, from its Claude Code transcript —diag loop-reportcounts mxcli processes; this reads the transcript (~/.claude/projects/<project>/<session>.jsonl, subagent transcripts included) and reports model calls, tool calls by tool, cache-read / cache-write / output tokens and wall time; Bash calls split into mxcli verbs, playwright, build, git and other; every call in one category (orientation, write, validate, apply, verify, diagnosis, retry, delegate, other); the costliest results by re-read cost (size × the model calls after it, up to the next compaction); error → retry chains aggregated by normalised error; and repeated file reads and syntax/help/skill lookups. Several transcripts give one report each plus a combined one;--json,--top N. The output carries counts and short command/path/error snippets only, so it can be shared without the conversation. Rules: docs-site "Measuring Agent Sessions".mxcli eval runand theBENCH-001benchmark brief — runs Claude Code headless (claude -p, permissions bypassed, a known session id) on an eval test in a fresh project made bymxcli new(so the agent gets the CLAUDE.md and skills a user gets), copies the session transcript and its subagent transcripts into the run directory, writesdiag session-reportfor it, then runs the test's checks. Variables a hosting Claude Code session sets for its children (CLAUDECODE,CLAUDE_CODE_*) are not passed on.docs/14-eval/eval-bench-001.mdis the fixed brief for measuring the agent loop: four entities, three associations, overview and edit pages, a validated microflow, two module roles, navigation and a microflow test. New eval checks:association_exists,module_role_exists,file_exists,tests_pass(--skip-tests).- The mxcli companion: a Claude Code mod with a Project pane —
/mxcli-projectopens a pane showing the app's structure (frommxcli project-tree) and the selected document's MDL (frommxcli describe). The tree reloads when the agent changes the model. From 90 columns the tree and the source sit side by side. The first session in which it loads offers the pane once, in a band above the prompt.mxcli initinstalls it in.claude/skills/mxcli-companion/andinit --sync-skillskeeps it current.project-treenow marks each nodedescribable, derived from describe's own dispatch, so a client never offers a nodedescribecannot answer (a JavaScript action and the Navigation node could not be described before). mxcli fix property-sets— complete the property names of units no write reaches (#1373) — every write now normalizes a unit's property names for the project's Mendix version (see Fixed), but only the units a statement rewrites.mxcli fix property-sets -p app.mpr [--dry-run]applies the same normalization to every stored unit and reports the keys added and stripped per unit. It goes through the ordinary guarded write path: no$IDorGUIDchanges, and a second run writes nothing. On Studio Pro-authored projects it reports 0 units.- DateTime
not localized(#1373) —BirthDate: DateTime not localizedsets Studio Pro's Localize off, which had no MDL spelling and was only carried on a rewrite. Barelocalizedswitches it back on inmodify attribute; unstated keeps what is stored.describe entityprints it when it is off.alter entity … modify attributeno longer resets a stored non-localized DateTime when the statement does not mention it. A view attribute follows its OQL source, and changing a source attribute's Localize now re-derives every view over it instead of leaving them CE6770 "out of sync". - Module documentation and the administrator's user name (#1314) — the doc comment before
create [or modify] moduleis stored as the module's domain model documentation and printed back bydescribe module;alter app security ( AdminUserName: '…' )renames the built-in administrator. Lint could already read both; MDL could write neither. close page ncloses n pages — the count was written to a field Mendix removed in 8.11, soclose page 2closed one page, and a Studio Pro "close 2 pages" described asclose page;. The parser now accepts the count, and the writer and reader use the current field.add $X to $Obj/Module.Assocandremove $X from $Obj/Module.Assoc(#1288) — the Change object activity's add and remove on a reference set.change $Obj (Assoc = $X)was the only spelling and assigns the whole set, so appending in a loop kept only the last row, with no error from check,mx checkor the runtime.Param = nothingfor a call argument left blank — Studio Pro stores a blank call microflow / call nanoflow argument as an empty mapping, anddescribeprinted it asParam = ,, which did not parse. It now prints, and accepts,Param = nothing.check --v1=warn|error— mirrors--deprecations: undererror, every MDL-V1-* warning (a headerless script not ready formdl 1;) fails the run. A script headedmdl 1;reports none.mxcli test --db-type postgresql|hsqldb(#1274) — a--localsuite can run on the file database, asrun --local --db-type hsqldbalready could, so a machine without PostgreSQL can run tests.- MPR007 flags a user role that cannot open its home page — a role none of whose module roles may open the home page it lands on passed lint and
check --references, then failed the build with one CE2729 per widget, none naming the cause. The warning resolves each navigation profile's effective home page per role, and states CE2729 only where the project runs at Production security. - The language poster — all of mxcli and MDL on one page, interactive (zoom into any panel, or step through it as a 19-panel tour), shown at the top of the README and in the manual's Preface.
Changed
- A page or snippet variable's default is written as a bare expression —
Variables: ( $show: Boolean = true ),= if (3 < 4) then true else false,= 'Price' + ' list',= Module.Enum.Value, and the same inalter page … add variables. The old spelling, a string whose content is the expression (= 'true'), keeps its meaning under every language version and warns as MDL-DEPR086 (refused frommdl 2).fmt --upgraderewrites it, anddescribeprints the bare form. A default that is itself a string ($s: String = '''abc''') or is empty keeps its current spelling and is not reported, since a bare'abc'is the old spelling. - A published OData service's authentication is a property —
create published odata service M.S ( …, Authentication: (basic, session, microflow M.Authenticate) ), in the order written, replaces the trailingauthentication basic, sessionclause (R9). The property can also sayAuthentication: none, which the clause could not, andalter published odata service M.S set ( Authentication: … )now changes authentication on an existing service — before, it could only be restated with the whole service. Left out,create or modifyandalterkeep the stored setting, as before.describeprints the property. Migrating a script: nothing breaks — the clause (MDL-DEPR139) still parses and builds the same service,check/execwarn, andmxcli fmt --upgrademoves it into the list (a clause naming a method MDL has no keyword for, e.g.authentication Custom, is reported and left alone). A stored setting MDL cannot state — a microflow stored without the Microflow method, or the reverse — is now a comment indescriberather than printed asMicroflow M.F, which used to add the method when the output was executed. Executing thedescribeoutput of each of ako/TestApp's three Studio Pro OData services writes nothing. call rest servicetakes its settings as one property list (ADR-0013) — the activity's dialog settings go in one( Key: value, … )list after the URL, keyed as the consumed REST service names the same concepts:$Html = call rest service get 'https://example.com' (Headers: ('Accept': 'text/html'), Authentication: basic (Username: $User, Password: $Password), Timeout: 300) returns String;.Body:istemplate '…' [with ({1} = …)],mapping M.EMM from $Var,binary <expr>or an expression. The method, URL,returns …andon error …stay words. An unknown or repeated key, or a value of the wrong shape, is an error.describewrites this form. Migrating a script: nothing breaks — the clausesheader 'N' = v,auth basic $u password $p,body …andtimeout n(MDL-DEPR720) still parse and store the same activity,check/execwarn, andmxcli fmt --upgraderewrites them; a statement cannot mix the two forms. ADR-0013 makes this the rule for every new microflow activity and every activity with several settings.run --local --page-checksigns in with--screenshot-userwithout--screenshot, and checks all pages in one browser — the sign-in only ran when--screenshotwas also given, so--page-check --screenshot-user Ureported every secured page as the login page. The verdict also no longer counts a list view's "No items found" placeholder or a data grid's header as rows, ignores the demo-user switcher's "Select user" heading, and reports a failed same-origin request (HTTP 560 POST /xas/) instead of the duplicate "Failed to load resource" console line. The login script used by--screenshot-userfalls back to/login.htmlwhen the app root does not show the sign-in form, and finds Playwright the way the page check does (noplaywrightCLI onPATHneeded).mxcli renametakesjava-actionandworkflow— the subcommand offered eight of the ten targetsRENAMEaccepts; Java actions and workflows could only be renamed from MDL.mxcli rename -p app.mpr java-action M.JA_Old JA_Newalso renames the.javasource file, and both updatedocs/brain/anchors like the other types. The type list is now held to the grammar by a test, so a newRENAMEtarget cannot be left out of the subcommand again.mxcli syntax renamedocuments both forms. (follow-up to #1318)- An in-place edit inside a loop body is spliced, not refused (ako#1106) — under
mdl 1;, re-runningcreate or modify microflowwith one changed expression inside a loop was refused with MDL-V1-REBUILD, so one script could not both provision and update a flow that loops. A body of the same shape (same statements in the same order) is now edited in place, nested loops included, andalter microflowaccepts a one-for-one replace of an activity in a loop. Adding, removing or moving a node in a body keeps the refusal. - Agents are routed to
mxcli syntaxbefore a skill, and every skill has a section index — the generated CLAUDE.md points atmxcli syntaxas the first stop for how to write any MDL, and each of the 74 skills starts with a generated, line-numbered section index, so an agent can read one section rather than the whole file. Reading whole skills was ~68% of a benchmarked session's re-read cost. - Faster on large projects, MPR v1 above all — on MPR v1 every typed listing read the contents of every unit before filtering by type; listings now filter on a type index first.
check -plists only the document kinds the script's statements can clash with, and reads the project settings only for a script that writes translations.describe microflowon a flow whose decisions call rules no longer runs for minutes (one rule lookup took 53 s on a 140 MB v1 app), and a hand-laid flow is analysed once per describe instead of once per layout round (#1301). - MDL-DEPR081 names the
$currentObjectform it means — the message saidVisible: <expression>had the same meaning asVisible: [<expression>]. It does not: inside the brackets a bare attribute is rooted in$currentObject. A migration done by hand from the message silently rebound every such condition. - Re-running
create or modify navigationreportsUnchangedwhen nothing was written, instead of "Navigation profile 'X' updated." every time.
Fixed
check -poncreate or modifyof stored microflows is back to v0.24.0's speed (#1272) — the passes that predict exec's verdict and resolve references looked each flow up by name several times per statement, and every lookup re-read and fully decoded every microflow file in the project, so the cost per statement grew with the project. Each check pass now reads a unit file once, and a lookup by name or ID decodes only the flows it returns. On a blank 11.14 app with 200 microflows, re-declaring 25 / 100 / 200 of them: 3.5 / 11.7 / 23.7 s → 0.8 / 1.8 / 3.0 s (v0.24.0: 0.9 / 2.6 / 3.7 s).execgains the same through its preflight and its own planning of each statement; an unchanged re-run of the 200 went from 40 s to 5 s. Nothing reported changes.- A navigation sub-menu no longer keeps the action of the page item it replaces (#1341) — turning menu item
'Work'into sub-menu'Work'withcreate or replace navigation(orcreate or modify menu) paired the two by caption and carried the page item'sForms$FormActiononto the sub-menu, reporting it as an action "MDL cannot express";mx checkthen failed with CE0548 "Items with subitems cannot have an action themselves." A sub-menu is now always written with no action (measured on 11.14.0). mxcli test --attachand the dev loop's "already serving" detection see a live app on Windows (#1284) — both read a pid from a handshake file (.mxcli/test-endpoint.json,.mxcli/run-local.json) and tested it withSignal(0), which Go supports only as Kill on Windows, so every pid read as dead:test --attachalways refused with "the app that published … is no longer running" while the app was up, and a command that looks for a dev loop already serving the project (the recompile warning, for one) never found it. Liveness is nowinternal/procalive.Alive, which uses OpenProcess and WaitForSingleObject on Windows (the checkrun --localalready used for mxbuild) andSignal(0)elsewhere. No change on Linux or macOS.run stopon Windows no longer reports a run that has shut down as still alive — it printed "failed: 1 process(es) of pid N's run are still alive" and exited 1 for a run that had stopped, because its liveness check counted any pid Windows could still open as alive, and an exited process stays openable while its parent holds a handle to it. It now uses the same check astest --attach(above), and reports "stopped: pid N".retrieve $u from $obj/System.ownerpassed check and exec, then failed the build with CE0136 (#1358) —ownerandchangedByare entity flags, not modelled associations: mxbuild resolves the name in a retrieve by association but derives no entity from it,[CE0136] "Retrieve object must specify the 'Entity' property.", with or withoutowner: AutoOwner(measured on 11.12.2,System.changedByalike).checkandexecnow refuse it as MDL-RETRIEVE02 and name the form that builds:retrieve $u from System.User where [id = $obj/System.owner] first;.run --localandtest --localwork on Windows without Developer Mode or admin rights (#1286) — the first run for a new Mendix version failed withlinking runtime into mxbuild cache: symlink …: A required privilege is not held by the client.mxcli links the downloaded runtime into the mxbuild cache, and an ordinary Windows user may create a symbolic link only with Developer Mode or an elevated token. When Windows refuses the symlink, mxcli now makes a directory junction instead, which needs no privilege (the same linkmklink /Jmakes; it needscmd.exe, which every Windows has). The other link site, the PAD filesdocker buildlinks into the mxbuild cache, gets the same fallback. A cache that was already linked by hand withNew-Item -ItemType Junctionis left as it is.run --local --watchapplies a domain model change on Windows (#1342) — page and microflow edits hot-reloaded, but adding an entity or an attribute failed every rebuild with "The process cannot access the file '…\deployment\web' because it is being used by another process", and the app then served 404 untilrun --localwas restarted. A domain model change makes mxbuild recreatedeployment/web, and the incremental web client bundler runs inside it, which Windows will not let anyone delete. On that failure the watch loop now stops the bundler, builds again, and starts a fresh bundler on the newweb/; page edits keep the incremental path. Applies to Mendix versions whose deployment hasweb/rollup.config.mjs(reported on 11.12.4, reproduced on 11.13.0); 11.12.6 and 11.14+ bundle in mxbuild and were never affected.run stopandrun statusfind a detached run's processes on every machine — the guard against a reused session id rebuilt each process's start time from the kernel's boot time, which is whole seconds, and allowed only one second of slack. On a machine that booted late in a second, a run's own processes read as older than the run and were skipped, sorun stopcould report "was not running" for a live run. The slack is now two seconds. This was also the intermittentTestRunStop_*/TestSessionMembers_*failure on CI.- The catalog names a call's and a delete's target (#1305) —
activities_for()andCATALOG.ACTIVITIESreturned every microflow, nanoflow, Java action and JavaScript action call withaction_ref="", and every delete withentity_ref="", althoughrefs_from()had both targets; a loop-scoped lint rule could not follow a call out of the loop.action_ref/ActionRefis now the called document,entity_ref/EntityRefa delete's entity (when the flow types the variable: a parameter, a create or retrieve output, a loop iterator), and the newqueue_ref/QueueRefthe task queue a microflow or Java action call runs in, so a rule can skip a call that runs asynchronously. A nanoflow's JavaScript action call now has arefs_from()callrow (target_type"JAVASCRIPT_ACTION"), soshow callerssees it. The catalog schema is bumped to 23; a cached catalog rebuilds. - A DataGrid 2 column's
Visible:expression is written —Visible: $showPrices,Visible: if … then … else …,visible: not(…)andVisible: [cond]on a column passedcheckandexecand were stored astrue, so the column was always visible; only the old quotedVisible: '<expr>'was kept.alter page … set (Visible: <expression>) on grid column(…)was refused as "column property VisibleIf not found", and an inserted column droppedVisible: falsetoo.describenow prints the bare expression. A column's visibility is evaluated once for the grid, with no row object, so$currentObjectthere is CE0117 at build;checkrefuses it as MDL-WIDGET43 (measured on 11.14.0). Use a page variable or parameter. Projects regenerate their widget definitions (generator version 18). set $Param = …on a parameter is refused — a Change variable cannot target a parameter, and mxbuild rejects it with CE7247 "Parameter 'N' cannot be changed." (measured on 11.14.0 for Integer and String parameters in a microflow, a nanoflow and a rule).checkandexecpassed it. MDL-SET01 now refuses it for every parameter but a list (seton a list parameter is a Change list Replace, which builds), andexecenforces the rule. Copy the parameter into a variable first:declare $Value Integer = $N;.checkrefuses a button that passes its own data container by widget name (#1324) —actionbutton btnOwn (Action: call microflow M.F(Gate = $dvGate))directly inside data viewdvGatepassedcheck --referencesandexec, thenmx checkreported[CE0117] "Error(s) in expression." at Action button 'btnOwn'. A data container's name is a variable only for the containers nested below it; in its own context the object is$currentObject. Reported as MDL-BUTTON02 (error, soexecrefuses it), for data views, list views, galleries and data grids alike, including attribute paths ($dvGate/Name) and a control bar inside the container. The rule covers every slot evaluated in that context, not only action arguments: a nested widget's microflow data-source arguments,Visible:,Editable:andDynamicClasses:(CE0117), and a nested list's XPathwhere(CE0161). A grid's own name from its control bar (the selection) and an enclosing container's name from a nested one are not flagged. The flagged set matches mxbuild 11.14.0's CE0117s widget for widget on a ten-button probe page.set $Obj = …on an object variable is refused (#1323) — with both variables single objects (e.g. a Reference retrieved from its FROM entity),set $Cursor = $Next;passedcheck --referencesandexecand was written as a Change variable action, which mxbuild refuses with CE7247 "Variable 'Cursor' does not have a primitive type". Mendix has no action that reassigns an object variable, socheck(MDL-SET01, for the objects it can see without a project),check --referencesandexecnow refuse it and name the alternatives (a sub-microflow that returns the next object,change $Obj (…)).check --referencesnow types a Reference retrieve from its FROM entity as the object it is.seton a list variable stays a Change list Replace (ako#949).RENAME JAVA ACTIONrenames the Java class, not just the file — renamingM.JA_OldtoJA_Newmoved the source toJA_New.javabut leftpublic class JA_Old, its constructor and itstoStringinside it, which javac rejects (class JA_Old is public, should be declared in a file named JA_Old.java). A full build hid it, because mxbuild regenerates the stub in its own copy;run --local --watchhot reload and IDEs compile the file on disk. Those three places now follow the rename exactly as mxbuild rewrites them; user code and extra code are left as written. Applies tomxcli rename java-actiontoo.run --local --watchstarts on Mendix 10.24 and 11.6 — it waited the full web-client timeout (5 minutes) for a bundle that had finished in seconds, then failed withweb client watcher timed out. The rollup runner those versions ship reports its status as{"code":"SUCCESS"}rather than the modern-web-bundler protocol mxcli was reading; both are now understood, including that runner's error reports.run --local --watchno longer loses a change made while the app boots — the watch loop took its baseline after the boot, so a model written during the ~15 s boot was never built and the app kept serving the model from before it. The baseline is now the source time the boot build was made from, so that change is built on the first tick.- Documents mxcli writes are mergeable in Studio Pro (#1373, ako#1097) — Mendix's merge and diff engine compares an element's property names between two revisions and throws ("Objects with ID … do not have the same properties") instead of filling a default. A new element failed one Studio Pro save later, and
mx check, the build and the runtime never noticed.- Every written element gets Studio Pro's full property set, from a table measured with
mx converton Mendix 10.24, 11.6 and 11.12–11.15. Keys a project's version does not declare are stripped (refused when they hold a value), and keys Mendix removed before it are dropped. - On Mendix 10 and 11.0–11.11 projects, mxcli no longer writes types and keys those versions lack: no
Rest$JsonBodyon Mendix 10 (Studio Pro could not load the project at all; the body is written as a string body), and no 11.12-only published member types or navigation sync flag. - Writer gaps fixed on the way: a loop's documentation was never written (a rebuild erased it), a tab container's default tab never landed, a date-only attribute had no Localize key, an expression-bound page flow argument had no
Variableslot, inline REST value mappings carriedIsDefaultType, andResponse: nonecame back asjsonafter Studio Pro's next save. - A user role written by an older mxcli has no GUID, which mxbuild then re-invents on every build. It is filled with the role's
$ID, which kept the runtime's role rows and every user-to-role link (measured on 11.15 with PostgreSQL).
- Every written element gets Studio Pro's full property set, from a table measured with
describe→execof a Studio Pro microflow keeps its control flow — each of these described a flow that re-executed to a different one, found on real Marketplace modules:- a loop whose header sits in a branch, or is also the join of an
if, lost its back-edge, so a pagination or poll loop ran once; - an error handler two activities share was printed as two empty handlers, and one that runs through a merge with a single way in was cut off at that merge;
- an activity with no outgoing flow that ends a loop-body branch now ends in
continue;instead of falling into the code after the branch; - a region two
casearms share is printed once, a crossed merge is joined wherever a branch reaches it, and an interleavedifwhose entries are merges is joined instead of nested as fall-through; - an empty decision caption (#1254),
@excludedon an activity (#1328), a nanoflow'sgrant execute(#1345) and interior blank lines in a/** */doc comment (#1300) are kept; - an unspaced minus after a name (
$P/Offset-1,$I/OEE-$B/OEE) is subtraction, not part of a hyphenated name, so Studio Pro's stored expressions parse.
- a loop whose header sits in a branch, or is also the join of an
describe→execof a Studio Pro page or navigation changes nothing — layout grid rows and columns keep their design properties, classes, styles and alignment, a text input keeps its submit behaviour and delay, a layout grid its width and a column its preview width, and a static open-link address andWidgetslists are written exactly as Studio Pro stores them. A menu caption with an apostrophe parses again (#1343), and a folder name containing/is escaped as\/instead of being filed three folders deep (#1367).check -ppredicts whatexecrefuses, in more places:- a set of script files is checked against what the earlier files write, so a later file's reference to something an earlier one creates is no longer reported missing (#1355);
grant,revokeand user-role statements resolve the entities, documents, members and roles they name, andcreate module roleits module (#1354); flow and page signatures resolve their entity types;- a retrieve constraint comparing an attribute with a variable of an incompatible type (#1325), and an operator inside an XPath function argument (MDL091, #1326), are refused before the build reports CE0161;
currentDateTime(), which is not a Mendix function, is refused (MDL044);- accepted, as Mendix accepts them: the parse functions' default-value argument (#1216),
:as division in a comparison,$obj/Assoc/Module.Targetas an object value (MDL049), the output name of a call to a void microflow or nanoflow, and ajoininside a REST call's error handler (MDL-FLOW02). A stored void microflow's return value is a warning instead of an error, soexecre-applies Studio Pro-authored flows; - no false MDL-WIDGET07 for properties the builders do write (
ShowFooter, a navigation tree'sMenu, …; #1346), or for a pluggable widget named by id when there is no project; - clearer syntax errors for
drop … M.F if exists(it isdrop … if exists M.F) and for a hyphenated icon name (Atlas_Core.Atlas."add-circle"), and a syntax error instead of a crash for a non-string REST property value (#1331).
- Page and model writes that passed
checkand failed later:- a button's
Tooltip:is stored, described and alterable (#1307);alter pagecan insert a tab page into an existing tab container (#1215); - a flow argument on a button inserted into a snippet, or set with
alter page … set (Action: …), binds the parameter instead of writing$Pas text (#1317); changedBy/Nameandowner/…in a widget's attribute path resolve the System associations (CE1613, #1338), a bare association name invalidation feedbackis stored as an association, and a cross-module association published on an OData entity is published as an association end (CE1613);- adding
(KEY)to a published OData member no longer carries its stored "can be empty" onto the key (CE0309); - a Boolean constant's default and override are stored as
True/False, as Studio Pro reads them (#1321); an underscore-led enumeration value in XPath (M.E._True) is stored as Studio Pro stores it (CE0161); a restrict association's delete message is stored in the project's language instead of en_US (#1344); a Microflow-typed Java action argument followed by a line break resolves (#1282); consecutive XPath predicates (Entity[a][b]) parse (#1281).
- a button's
- Lint: CONV011 and MDL-PERF01 count
create … commitandchange … commitin a loop as a commit in a loop, and MDL-MAP04 checks import and REST activities already stored in the model, not only those in a script (#1319). - Tools:
mxcli describe Mod.Namefinds documents when there is no catalog, and thedescribesubcommand accepts published REST services (#1347);- an implicit catalog rebuild no longer counts against the statement timeout, which on a large app cut it off at 5 minutes and repeated it on every call (#1329);
describe structure depth 2|3lists each page's data widgets, which it never had;mxcli newno longer exits 1 when the devcontainer's Linux binary cannot be downloaded after the project was made;playwright checkfinds mxbuild 11.15's bundled node;diag loop-reportcounts the wall time of runs that wrote no summary, which hid the app restarts;- three skill examples that failed
mxcli checkare fixed, and whole skill examples are now gated on it (#1357).
Full Changelog: v0.25.0...v0.26.0