Repository navigation
v0.27.0
[0.27.0] - 2026-10-15
Headline: exec is all or nothing: when a statement fails at write time, the whole run is rolled back, so a script never leaves a project half-changed. Alongside it: a wave of describe → check → exec fixes from round-trip runs over real apps (the Siemens FSM template, the GenAI showcase, Marketplace modules), Mendix 9 projects can take microflows, nanoflows and pluggable widgets again, check -p resolves many more of the references exec and the build would refuse, the classic filemanager widget and role-based Visible: roles (…) are in MDL, and the companion draws a module's domain model. The MongoDB driver is upgraded for the October 2026 BSON advisories.
Added
mxcli search --fail-on-matchturns the search into a gate — a pipeline that must refuse a change when a forbidden word turns up in the project's text had no exit status to read:searchexited 0 whether it found something or not. With the flag it exits 1 when there is at least one hit and 0 when there is none, printing the results as before (a JSON array under--json). A search that cannot run, such as an unbalanced"or an unknown project, exits 2 so that 1 always means a match; theSEARCHstatement still answers an unrunnable query with "No matches found.". Without the flag a hit exits 0 as before. Rules: docs-site "Full-Text Search".filemanager— the classic file manager (Forms$FileManager) in MDL (#151) —filemanager fileManager1 (Label: 'File', Type: Upload, MaxFileSize: 10, AllowedExtensions: '.xlsx', ShowFileInBrowser: false)inside a data view on aSystem.FileDocumentspecialization. Before, there was no way to author one:pluggablewidget 'Forms$FileManager'had no definition, the bare keyword was refused as MDL-WIDGET25, anddescribe pageprinted a stored one as a NOT re-executable comment, so describe → exec dropped it. Omitted properties take Studio Pro's defaults (Both, 5 MB, any file, false); the written BSON has the property set of a Studio Pro-authored file manager.alter page … setchanges all four properties. A file manager in no data container is MDL-WIDGET45 atcheck, and one in a data view on an entity that is not a FileDocument is refused byexec— both were mxbuild's CE6810 after a cleanexec.- A module's domain model as SVG, in the companion and on the command line —
mxcli describe --format svg domainmodel <Module>writes a finished SVG: entities at the positions the model stores, coloured by kind, with attributes, associations, multiplicities and generalizations. Boxes are sized to fit every name, pulling the stored layout apart just enough instead of clipping. In the Claude Code companion, selecting a module's Domain Model node in the desktop app or VS Code shows it at actual size, with pan, Fit and a full-width view; the terminal lists the entities as before. Visible: roles (Mod.A, …)— role-based widget visibility (#1460) — Studio Pro's "visible for module roles" was never read bydescribe, had no MDL spelling, was written empty and was dropped byalter … set Visible. It is now read, written and combinable with an expression or attribute condition, on widgets, tab pages and navigation list items. A tab page's (#1465) and a layout grid row'sVisible:(#1461) are now written too;describe→execused to make a Studio Pro row always visible.+=/-=for reference-set members insidechange(#1473) —change $Obj (Name = 'x', Mod.Assoc += $Item): a Change object activity that mixes an Add or Remove with other members had no spelling, anddescribeprinted the Add as=, which replaces the set.- ALTER PAGE addresses navigation list items and widgets inside pluggable widgets —
nav item('Home'),nav item(t1)andnav item@2name an item by its text, a widget in it, or its position;insert into navList1 { item … }adds one (#1388). Widgets inside an Accordion group or a pop-up menu item, legacy DataGrid columns and search fields, and a file manager's own properties can be set and dropped (#891, #1459, #151).setalso writes a text box'sPlaceholder,PasswordandValidation(#414), a static image'sImage(#1464), and aLabelon an input that showed none (#292). Image: $currentObjectbinds the Image widget to an uploaded image (#1476) — no MDL form bound the pluggable Image widget to the object in context; it is refused outside a data container or over an entity that does not extendSystem.Image.describe module --all(#1435) — thedescribe modulesubcommand printed only the module and its roles although the help promised "all contents";--allrunsdescribe module … with all, and the help says what each form does.with allnow emits every document type, where it skipped nanoflows, snippets, JavaScript actions, mappings, task queues and image collections without an error (#1421).mxcli test --app-port / --admin-port / --serve-port—test --localhard-coded its ports, so a machine with 8081 taken could not run tests. A taken port fails up front, naming the port, its role and the flag that moves it.mxcli layout --only-overlapping(#1479) — and a new entity without@Positiontakes the first grid slot that clears every entity and annotation in the module, so an entity with many attributes no longer overlaps the one below.- SEC010 flags page data widgets their roles cannot read — a list view, data grid, reference selector or pluggable combo box over an entity none of a page's roles can read renders empty, with check, mxbuild and the runtime log all clean. SEC010 now asks, per user role that can open the page, whether any of its module roles has a read rule, using the System module's access rules measured from a built model, and reports a System.User list that only ever shows the current user.
mxcli syntax microflow workflow-actions— a topic for the microflow statements that start and manage workflows.
Changed
- mxcli no longer creates a module role on its own (#1474) — a new page, microflow or nanoflow in a module with no module roles used to create
<Module>.User("Auto-created default role for mxcli document access") and grant the document to it, so a security role appeared that nobody chose, open to every user role later mapped to it. A new document now starts with no allowed roles in every module, andmovemaps a document's roles to same-named roles of the target module without creating any. Breaking for scripts that granted to<Module>.Userwithout creating it: addcreate module role <Module>.User;—check --referencesandexecboth report "module role … does not exist", and MDL-SEC21 names the fix for a flow a page uses. Roles and grants an earlier mxcli created are left as they are;create module role M.Userstill adopts such a role. check -presolves many more references beforeexecwould refuse them (#1472) — each of these passedcheckand failedexecor the build (CE1613, CE0174):- ALTER PAGE targets and the flows, pages, snippets and entities inserted widgets name, and DataGrid 2 column attributes against the grid's entity;
- the members an access rule's
wherenames (case-insensitively, as Mendix does), an entity event handler's microflow, enumeration keys named in expressions, and the entities a view entity's OQL reads from; - image references against image collections the script creates (#1419), and calls to flows the script creates, including mutually recursive ones, which no statement order could check before (#1405);
- object-list item properties that would be dropped (
group g1 (Caption: …)in an Accordion, whose header isheaderText), and a file manager outside aSystem.FileDocumentdata view (CE6810); - a
changeor member path over a list retrieve (MDL-RETRIEVE03, #1422),show message … type ok(MDL-SHOWMSG01),import from mappingwithout a result entity, which made the project unloadable (#1418), andalter settings JavaVersionon a Mendix 9 model, which stores none (#1438).
- A multi-file
checkends on a verdict for the whole set (#1431) — "N of M files failed: …" or "All M files passed", where the last line used to be the last file's verdict, which could read "Check passed!" with exit code 1. - Commands without
-pname the project they auto-detected (#1444) — the notice gives the absolute path and how to choose another, and with several.mprfiles in the directory it lists them and asks for-pinstead of only saying-pis required. - Studio Pro document names in
describe --helpand the catalog (#1395) —consumedrestservice,publishedodataservice,taskqueue,aimodel,appsecurity, …, and catalog viewsconsumed_rest_services,published_odata_services,task_queues, …. Every old keyword and view name still works. mxcli syntaxresolves statement verbs and stops teaching deprecated spellings (#1389) —mxcli syntax grant(andrevoke,refresh) found no topic, and several examples used spellingscheckflags as MDL-DEPRnnn.- One-shot mxbuild runs have a timeout and a stall watchdog —
mxcli newanddocker buildcould hang forever behind a Gradle build that stopped making progress. They now stop afterMXCLI_MXBUILD_TIMEOUT(30 minutes) orMXCLI_MXBUILD_STALL_TIMEOUTof silence (10 minutes), printing the last output lines and the Java home used. mxcli inittitles the generated docs after the app, not the repository folder, and the bootstrap script defaults to the release that generated it instead of nightly, and fails loudly when database provisioning fails.
Fixed
mxcli searchandSEARCHfind words that appear only in an element's documentation (#1477) — the strings index held captions, messages, URLs and the documentation of microflows and workflows, but not the documentation of entities, attributes, associations, enumerations, constants, pages and the other documents whose catalog tables carry it, so a word present only there answered "No matches found." (measured: a word in a constant's documentation was found byselect … from catalog.constants where Description like …and not bysearch). The index now also holds those: each hit names the element (ObjectTypeENTITY,ATTRIBUTE,CONSTANT,PAGE, …; an attribute isModule.Entity.Attribute) and the field (StringContextdocumentation), the labels microflow documentation already used, plus the parameters of microflows and Java actions and a module's domain model documentation (domain_model_documentation). A module's own rows carry the module's name inModuleName, not the empty string theobjectsview holds for a module. They are read from the tables the catalog builder has just filled, not from a second walk of the model; building a catalog of a stock 11.12 app takes the same time (0.5s) and the strings table grows by about 50 rows. Enumeration values are not indexed (Mendix has no documentation field on them), nor is the summary text of a remote service's contract entities. The catalog schema version is bumped to 25, so a cached catalog is rebuilt once. Rules: docs-site "Full-Text Search".searchfinds a microflow's log message (#1477) — only the log node name was indexed. A log message is a plain-textMicroflows$StringTemplate, not aTexts$Text, so the walk that finds every translatable text never saw it, and a word present only in a log message was not found. It is now alog_messagerow beside thelog_nodeone (activities inside a loop are not reached, as before for the node name).checkrefuses a widget datasource constraint that reaches two hops off a variable (#1466) —database … where [Name = $currentObject/Mod.Assoc/Name]on a combobox, list view, data grid 2 or gallery passedcheckandexec, then failed the build with CE0161. MDL055 covered only microflow retrieves; it now covers page datasources too. One hop ([Mod.A = $currentObject/Mod.B]), the context object's own attribute and the inverted form all build at 0 errors on 11.13.0 and 11.14.0 and stay accepted.execrolls back when a statement fails after the pre-check (#1408) — a statement that failed at write time left every earlier statement written: a created module stayed, and adropahead of the failingcreatewas not undone. A before-image journal copies the.mprand each unit file the run touches before its first write, and restores them on failure. The message says "Nothing was written: statement N was rolled back".- Mendix 9 projects — microflows and nanoflows could not be created or altered in a 9.x project, and every page holding a pluggable widget failed to write, because mxcli wrote properties those versions do not have (#1410). Both are now written in the shape the project's version stores.
run --localpicks JDK 17 for a Mendix 9 project (#1437), and a create accepts an enumeration split of more than 16 branches, as Studio Pro 9 writes (#1416). describeoutput thatcheckorexecrefused, found by round-trip runs over real apps:- an index on a system date member printed an empty column list (#1401); a parameter's separator landed inside its doc comment (#1412); a JavaScript action with type parameters and an undeclared Java action type parameter did not parse (#1404); a doc comment line starting with
*lost its bullet on each round trip (#1428); - a native pluggable widget's child slot was printed as
content { }(#1400), a Mendix 9 pluggable database source was dropped (#1399), a data view listening to a legacy data grid named a widgetdescribecannot emit (#1415), a data view sourced from a snippet parameter had no data source (ako#1138), and a layout built on another layout printed an empty body (#1411); - a decision on a rule that returns an enumeration (#1414),
show pagepassing the page's own parameter by name (#1403), a$var/Attrtext template parameter (#1406),DecimalPrecision: -1and a primitive-array mapping root (#1407), and an aggregate whose output a latersetchanges (#1413) are now accepted; on erroris accepted, and described, on list operations, aggregates, create list, add/remove, cast, rollback and show home page (#1252);describe user rolealways statesCheckSecurity(#1427), a navigation list item keeps its class, a layout keeps its stored canvas size, and a statement whose output hits the 10,000-line limit fails instead of stopping mid-statement with exit 0 (#1425);- the
describesubcommand describes rules (#1402) and System Java actions (#1445).
- an index on a system date member printed an empty column list (#1401); a parameter's separator landed inside its doc comment (#1412); a JavaScript action with type parameters and an undeclared Java action type parameter did not parse (#1404); a doc comment line starting with
- Model writes that passed
checkand broke the build or the app:- a multi-hop association data source wrote one step for every hop, where it stored the second association as an entity (CE1613) or made the project unloadable (#1467); a DataGrid 2 column inserted into a flow-sourced grid gets its attribute reference (#1468);
- quoted names are stripped in a multi-predicate retrieve constraint, where
["A" = 'x']was a string literal and the constraint always false, and in an expression slot followed by whitespace (CE0117);expose (…, "Description")in an OData service is unquoted (#1423); - a list sort's inherited attribute is qualified with its declaring entity (#1430), export mapping members are written in message definition order (CE5015, #1387),
show message … type erroris stored asError, which the runtime showed as Information (#1280), and a module-qualified association hop in an attribute path parses; create or modify entitykeeps an index's GUID when its declared ID misses, where the write was refused (#1470);revokeresolves association members instead of reporting "nothing to revoke" (#1225); names with an excluded twin resolve to the live document inshow access,grant,revoke,drop pageandalter page, wheredropcould delete the live page (#1469);- a published REST service's authentication parameters are stated and described (#1417);
create or modify javascript actionkeeps the file's imports and EXTRA CODE (#1429); DataGrid 2 columns with no caption or no attribute get the empty templates Studio Pro writes (CE0463);widget initno longer lets native widgets take overimageandradiobuttons(#1463).
- Marketplace —
marketplace update --save-editssaves local associations into the module, which the update deleted (#1502); the reference cache keeps action sources, so an untouched module is no longer refused as locally changed (#1441);installnamesmarketplace updatefor a module already present (#1442);download --outputaccepts a directory (#1443); a valid.mpkis no longer rejected over a data-descriptor CRC (#1488). - Tests and the dev loop —
@throwscatches errors fromcall java actionand the other call activities (ako#1164), a FAIL carries the raised error message,test --localno longer hangs after the tests when mxbuild starts a Gradle daemon (#1396),sync-java-depschecks the version Gradle resolves when two modules declare different versions (#1450), and macOS resolves the project's JDK instead of the/usr/bin/javastub, which mademxcli newspin in Gradle. diff-localnames units and revisions in its headers and renders page, nanoflow and layout changes, which counted as modified and printed no hunk (#1393).- SEC010 counts a specialization's rule only for the members it grants, so a System.User list whose names come out blank for non-admin roles is reported.
Security
- MongoDB driver upgraded for the October 2026 BSON advisories —
go.mongodb.org/mongo-driver/v2v2.6.0 -> v2.9.2 andgo.mongodb.org/mongo-driverv1.17.9 -> v1.17.10. A customer's release scan (Sonatype Lifecycle, blocking at CVSS >= 7) refused the published.exeover CVE-2026-107324 and CVE-2026-107325 — panics inbson.Raw.Validate(a binary element declaring a length ofmath.MaxInt32) andbson.RawArray.Validate(a zero-length array) — and CVE-2026-81521. mxcli imports only the BSON packages, never the mongo client, so CVE-2026-81521 (Client.BulkWritenamespace confusion) was never reachable; the twoValidatepanics were, on bytes read from a.mpr(modelsdk/canon/attributeref.go,modelsdk/mprread/generic.go,modelsdk/mpr/reader_raw.go,cmd/mxcli/cmd_fix_hashes.go), so a malicious project file could crash the CLI — denial of service only, no code execution. v2.9.2 is the floor for all three: CVE-2026-81521 was fixed in v2.8.2, regressed out of v2.9.0 and v2.9.1, and restored in v2.9.2. The upgrade also raises the declaredgithub.com/klauspost/compressrequirement from v1.17.6 to v1.19.2, which the same scan flagged — that module is pulled in by the driver for wire-protocol compression and is compiled into no mxcli build (it has nogo.sumentry and nogo version -mline). No source change and no API change; BSON encoding and decoding are unaffected.
New Contributors
Full Changelog: v0.26.0...v0.27.0