Repository navigation
Sync ako/mxcli: page round trips, combo box database mode, text-template params across associations, log with stacktrace, event handlers - #1646
Merged
Conversation
A button passing a widget's selection to a microflow or nanoflow - a grid's control-bar button, or a button passing a combo box's selection - is stored by Studio Pro as a Forms$PageVariable naming only the widget. Describe left it out, so check reported CE1571 on pages that build (13 of the 16 reports describe -> check gives on TestApp), and exec wrote the call with no argument at all: rebuilt from the description, the nine pages give 13 CE1571 on mx check 11.14.0. Describe now prints `Items = $grid` for a Widget-only variable on a flow call or flow data source. The builder binds `$name` that names a widget of the document to the Widget slot (after parameters and page variables, which win on a clash), and the writer stores it there with Expression "", as Studio Pro does. In-place describe -> exec of the affected pages: 0 errors, where the pre-fix binary gave 2 CE1571. Two TestApp pages now keep GetPut and are struck from the allowlist. Refs #1560, mendixlabs#1628 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jEcJZDio1jrTrWtVzagjY
A list view's `Action:` and a data grid's or gallery's `OnClick:` fire per row, and the row fills the flow's parameter in: Studio Pro stores the call with no parameter mappings (TestApp's ConflictedWorkflowDefinitionView, ConflictResolution and WorkflowDefinition_Overview grids). The CE1571 rule judged that action against the context around the widget, as for a button, and refused pages mxbuild builds: measured on 10.24.25, a list view, a data grid and a gallery with no argument give no CE1571, a button outside every data context does. The widget's own "Action" slot is now judged in the context its data source puts in scope; every other slot (a gallery's onSelectionChange) and the data source itself stay on the enclosing context. Show page has had the same rule since #552. Describe -> check over all 68 TestApp pages: 16 CE1571 before the two #1560 fixes, 0 after. Refs #1560, mendixlabs#1628 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jEcJZDio1jrTrWtVzagjY
…another entity
`alter page … replace cbBooking with { combobox cbSale (… from M.Sale …) }`
kept cbBooking's custom content inside cbSale: txtOptionName, bound to
Booking.Name. A same-kind replace keeps what the statement does not state
(mendixlabs#1247), and describe never prints a combo box's custom
content, so it was always kept. With the content type 'yes' mx check
reported CE1365 at a widget the author never wrote; once describe printed
the type, the replace turned it 'no' and the stale widget stayed stored,
hidden.
The stored Type says which data source content is built for
(DataSourceProperty). When the merge would keep that content while the
data source now names another entity, exec and check -p refuse, naming the
widgets: drop them first in the same statement, or drop + insert. check
counts drops earlier in the script, since it reads the stored document.
A replace that keeps the entity keeps the content, as before. Measured on
11.13.0: the reported replace is refused and nothing is written; with the
drop first, cbSale has no content and mx check is 0 errors; a same-entity
replace keeps it, 0 errors.
Refs #1563, mendixlabs#1631
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jEcJZDio1jrTrWtVzagjY
describe printed a combo box with custom content as if it had none, so its widgets were invisible until mx check named one. MDL cannot author custom content (MDL-WIDGET26), and the NOT SHOWN note for a slot holding widgets was only computed for generic pluggable widgets. A combo box whose widgets properties hold widgets is now described with a `-- NOT SHOWN:` comment naming the property and each widget, what keeps the content (this page, the combo box unchanged, or `alter page … set`) and what loses it (a changed combo box: CE0642; any other project). The output still parses, and describe -> exec of the repro page is still "Unchanged". Refs #1563, mendixlabs#1631 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jEcJZDio1jrTrWtVzagjY
…-trip-gaps-ibgvit
…e event `alter entity M.E add event handler on before commit call M.Second($currentObject)` failed with "event handler already exists for Before Commit" when the entity already had a Before Commit handler, though Studio Pro allows several handlers for one event and `create or modify entity` stores two `on before commit` clauses (mendixlabs#1540, #1438). ALTER keyed a handler on (moment, event) alone. Its identity is (moment, event, microflow): another microflow is a second handler; the same microflow again is still refused, which is what keeps a re-run from wiring it twice. The same key had made `add event handler if not exists … call M.New` skip with "already exists" whenever any handler for the event existed, and `drop event handler on before commit` remove whichever handler was stored first. DROP now takes `call Mod.Mf` to say which one; without it, a drop that matches several handlers is refused and names them. Measured on Mendix 11.12.4 with mx check: two Before Commit handlers are 0 errors (via the fixed ALTER, and via the old binary's create or modify); a void-returning Before Commit handler is CE7247, the control showing the check inspects handlers; the same microflow twice is also 0 errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SLbjUJghMMwekH4y5VEtBZ
make lint (fmt-check) fails on main with this file under go1.27.3, the toolchain go.mod and CI pin. Whitespace only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SLbjUJghMMwekH4y5VEtBZ
A pluggable widget's text-template parameter bound across an association
(`legendParams: ({1} = Mod.Parent_Child/Label)`) was resolved to the right
attribute and the right steps, and the serializer threw the steps away:
SerializeColumnClientTemplateParameter wrote AttributeRef.EntityRef null,
so mxbuild read the attribute against the widget's context entity:
[CE1365] "Attribute 'Repro.Child.Label' is not an attribute of entity
'Repro.Parent'."
The same serializer writes widget-level templates, object-list item
templates and Data grid 2 column templates; on a blank 11.12.4 app the
previous build fails CE1365 on all three (a Fieldset legend, an Accordion
group headerText, a dynamic-text column) and this one has 0 errors.
mendixlabs#1494, #1348.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCd38DLXnG1FLJGs1eM6LD
`describe page` printed a pluggable widget's (and a Data grid 2 column's)
template parameter over an association as the bare attribute, `{1} =
Label`, which re-executes against the widget's own entity: CE1613 "The
selected attribute 'Repro.Parent.Label' no longer exists."
The core describer had learned the `Assoc/Attr` path and its pluggable
twin had not — the drift upstream #977 found in the same pair, which
shared a helper and kept the loop duplicated. The core reader now
delegates to the pluggable one, which gains the association path and the
trimmed expression, so there is one reader of a template parameter.
mendixlabs#1494, #1348.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCd38DLXnG1FLJGs1eM6LD
mendixlabs#1495 (#1349) reported, against v0.24.0, an expression parameter stored as an attribute path with its spaces stripped: CE1613 "The selected attribute 'Repro.Parent.if1=1then'A'else'B'' no longer exists." v0.25.0 fixed it (#823); main stores the Expression and builds clean. The test takes the reporter's own spelling through the visitor and the parameter builder. Stubbing either guard reproduces one half of the reported message: token text instead of source text gives `if1=1then'A'else'B'`, and a builder that binds every value gives `M.Job.if 1 = 1 then 'A' else 'B'`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LCd38DLXnG1FLJGs1eM6LD
…tion The regression script for mendixlabs#1494 and #1495 — a Fieldset, an Accordion group and a Data grid 2 column bound over an association, and an expression parameter — plus the finding record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LCd38DLXnG1FLJGs1eM6LD
…xlabs#1617) DESCRIBE MICROFLOW printed a Show page action whose NumberOfPagesToClose is "1" exactly like one that closes none, and no statement could write it: the reader never read the key, the writer hard-coded "", and the show page `with` list ignored every key but title, location and modal. - The setting is `show page M.P with NumberOfPagesToClose = <expr>`, beside the title override. It is read, written and described; unstated stays "" (closes none). A literal that is not a whole number is refused (mxbuild 11.12.5: 1.5 and a Boolean are CE0117; 0, -1, 2 and `$Count + 1` build clean). - Any other `with` key is MDL-V1-PROP / MDL-V1-PROPVALUE (an error under `mdl 1;`, a warning without it). `location` and `modal` were read into PageSettings that no writer emits; Mendix deleted the location in 8.0. - The reporter's `show page M.P (NumberOfPagesToClose: 1)` is an argument for a page parameter of that name. check --references (and exec) now refuse an argument naming no parameter of the page, as the flow calls already did (#953): mxbuild fails it with CE1613, and is case-sensitive about it. The message names the `with` spelling. Control: with the fix reverted the new tests fail with the reported symptom (describe prints `show page X;`, the writer stores ""). Fixes #1550 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JQpG3nKq4SvijUdrXJRGSX
… ones MDL031 refused a CASE column over a String(8) attribute declared String(8) — "declared as String(8) but OQL expression returns String(200) … Fix: change to 'SortKey: String(200)'" — and following the fix was CE6770 "View Entity is out of sync with the OQL Query". exec runs the same check, so only --no-check could write the declaration that builds (#1294, mendixlabs#1250). inferCaseType returned the first branch it could type. Without the project a bare attribute is untyped, so in case … then l.Code when … then '0' + l.Code else '0000' end the concatenation in the second branch decided. A grid of one-column views, each declared at every candidate type and checked with mx check 11.12.5 (one accepted declaration per view), gives Mendix's rule, and it differs per kind: string CASE the FIRST branch's type, length included: then l.Code else l.Name (8, 100) -> String(8) then l.Name else l.Code -> String(100) then '0000' else l.Code -> String(200) numeric CASE widened over ALL branches, Integer < Long < Decimal: then 1 else 2.5 -> Decimal then l.IntV else l.LngV (and back) -> Long So "first branch decides" alone would have kept the numeric twin of the bug: `then 1 else 2.5` was typed Integer, refusing Decimal and suggesting Integer (CE6770). inferCaseType now applies both rules, and a branch it cannot type leaves the result unknown wherever that branch could decide it. The project-aware path types each branch against the project instead of falling back to the static inferrer, so with the source entity present the fix names String(8); a string CASE inherits its first branch's source attribute and with it the exact-length rule, and the refusal calls it a CASE column rather than a pass-through one. A string literal there is the derived String(200) (`'abc'` builds only as String(200)), not its own length. Control: with oql_type_inference.go reverted, oql_case_type_test.go fails on the reported case with the reported message. Full run on 11.12.5: the bug-test applied by exec with checks on is 0 errors in mx check; the declarations the old hint gave (String(200), Integer) are CE6770 on both views, and check -p now refuses them suggesting String(8) and Decimal. The mdl-entities skill and the view-entity syntax help said a string-returning CASE is always String(200); both now give the measured rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NH2drvgJU9wb8xgK2wXaxe
…mendixlabs#1618) `datagrid dg (…, itemSelection: Single)` and `gallery g (…, itemSelection: None)` passed check, exec and mx check and stored the value as the property's PrimitiveValue, with Selection left at the default — no selection on the grid, and no way to turn a gallery's default one off. The mapping pass read only the `Selection:` keyword; the explicit-key pass skipped "already handled" names by the mappings' source keywords, not their property keys, so the key fell through to SetPrimitive. - `Selection:` and the property's key (or an alias) are one property: both are read by the mapping pass and stored in Selection. The by-key grid's widget object is now identical to the keyword-spelled one. - A value that is not None/Single/Multi, or two different values under the two spellings, is refused by exec and by check (MDL-WIDGET50). mxbuild 11.12.5 accepts Selection "Bogus" at 0 errors, so nothing after mxcli catches it. - A definition constant the script overrides by key on a widget that does not declare the property (`advanced` on Gallery 3.4.0) is refused by exec, and by check -p from the installed package (MDL-WIDGET01). - The Gallery click-ambiguity rule (MDL-WIDGET36) reads the key too: `itemSelection: None` with an onClick builds at 0 errors now, where the pre-fix build failed mxbuild with "The item click action is ambiguous". Control: with the fix reverted the new tests fail with the reported values (Selection "None", PrimitiveValue "Single" for dgSingle; Selection "Single", PrimitiveValue "None" for galNone). Fixes #1552 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JQpG3nKq4SvijUdrXJRGSX
…he mistake
`create microflow Tmp.F returns Boolean as $b begin … end;` reported
line 1:23 missing '(' at 'returns'
line 1:31 missing ':' at 'Boolean'
line 4:2 extraneous input 'return' expecting the start of a statement
and `… Tmp.F $l: List of Tmp.Item returns …` "missing ')' at 'returns'"
after the first; the report asked for one message (#1396,
mendixlabs#1514). An earlier fix hinted the first error, but the
other errors stayed.
They come from ANTLR's recovery, not from the input: it inserts the
`(`, reads `returns` as a parameter name, lets the type swallow the
body up to the first `;` and closes the statement there. By the third
error the parser is back at program level (its rule-context stack is
just ProgramContext), so nothing in the error listener can tie that
error to the header any more.
So the grammar now accepts the bare header — `(LPAREN params? RPAREN |
params)?` on create microflow, nanoflow and rule — only so the builder
can refuse it, the pattern positional call arguments use (#569). The
refusal is the only error, sits on the token the `(` should precede,
and quotes the header back with them added:
line 1:23 a microflow header needs its parameter list in parentheses,
even when it is empty — they are not optional: write `create microflow
Tmp.F ($l: List of Tmp.Item) returns Boolean as $b`. See: mxcli syntax
microflow
The regex hint is removed: with the grammar accepting the shape it
could only fire alongside a second, unrelated error on the line, and
then it would have repeated the refusal.
Controls: the original code fails the new test with the three reported
errors; with the grammar change kept and the refusal stubbed out it
fails with 0 errors, so the grammar alone would have accepted a new
spelling. The test also requires the statement after the bad one to
parse.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NH2drvgJU9wb8xgK2wXaxe
…setting written as an argument Synthesizes the two fixes for the board's silent-property-drop cluster (mendixlabs#1617, #1618): a property reachable by its keyword and its key must be one name to every reader, and a setting the author wrote as a call argument is a dangling reference to close, not only a property to add. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JQpG3nKq4SvijUdrXJRGSX
A hide inside `A ? (…) : B ? (…hides…)` or `A ? (…) : B && hide(…)` was never lifted: its guard's boundary is the outer ternary's `:`, which parseGuard reads as "one fragment of a larger expression". Combo box selects its option source this way — "context"===t.source ? (…) : "database"===t.source ? (…) : "static"===t.source && hide(…) — so nothing the database or static source hides was known to be hidden, and a database-mode combo box kept the template's values for `optionsSourceType` and `selectAllButtonCaption` (CE0463, mendixlabs#1583). - elseChainTerms: an else-if branch's rule carries its own condition plus the negation of every earlier branch in the chain; an unreadable earlier condition fails the whole chain (no rule, the safe direction). - groupGuard / groupElseChain: an else-if GROUP's condition is the one bounded by the outer `:`, not the whole chain, and its hides carry the chain's negations. - An else-branch hide inside a guarded group (`G ? (…, C ? hide(a) : hide(b))`) carries G when the enclosing chain reads in full; otherwise its rule is the one lifted before. Blast radius, measured by dumping every lifted rule of every widget package in testdata/ and in blank 11.12.5 and 11.15.0 projects before and after: only Combo box (22 rules replaced by 71) and TreeNode (+1, exact) change. Every changed Combo box rule was checked against the editorConfig by hand. One consequence outside database mode: `selectedItemsSorting` no longer reads as hidden in association mode, where the editor shows it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J3X7yMohe1vQkLMqSGHj8e
unmappedHiddenResets skipped every property mapped in ANY mode of the definition, while the mapping loop it complements visits only the mode being built. A property mapped in another mode was written by neither: a database-mode Combo box hides `optionsSourceType`, which only the association mode maps, and kept the template's "enumeration" against a declared "association" — the last difference between mxcli's widget and the one `mx update-widgets` leaves, and the CE0463 (mendixlabs#1583). The function now takes the selected mode's mappings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J3X7yMohe1vQkLMqSGHj8e
…endixlabs#1583) combobox cbCode (source: 'database', optionsSourceDatabaseDataSource: microflow Mod.GET_Parents, optionsSourceDatabaseItemSelection: 'Single', optionsSourceDatabaseCaptionAttribute: Name, optionsSourceDatabaseValueAttribute: Name, databaseAttributeString: Code) check reported "3 issues: 0 errors, 3 warnings" (MDL-WIDGET06 "recognized but not yet persisted" for the datasource and the item selection), exec "Created page", and mx check "[CE0463] The definition of this widget has changed" at Combo box 'cbCode'. combobox.def.json had no database mode. The datasource had no write path, the explicit-key pass stored the Selection-typed item selection as a PrimitiveValue, and the caption and value attributes, linked to the unwritten datasource, bound to the data view's entity. - def: a `database` mode, selected by naming its datasource (`hasDataSource:optionsSourceDatabaseDataSource`; the generic `datasource:` clause stays the association mode's). `Attribute:` is the target attribute, `CaptionAttribute:` the option caption, `OnChange:` the mode's own `onChangeDatabaseEvent`. - engine: a Selection-typed key goes through SetSelection; a selection mapping reads its own key before `Selection:`. - check: the combo box's mode is the engine's own selectMode, not a restatement. MDL-WIDGET39 judges a database-mode target against String, Integer, Long, Enumeration, also when written as `databaseAttributeString:`. MDL-WIDGET16 requires the caption and, when a target is set (and the selection is not Multi), the value attribute. - describe: a database-mode combo box prints its datasource under its key, `Attribute:`, `CaptionAttribute:`, the value attribute, caption type/expression and a non-Single selection by key; its settings are no longer named as not reproduced. The generic `DataSource:` it printed before re-executed as an association-mode combo box. - widget describe: the generated example reads the unconditioned mode's constants only — the new mode's `source: database` had narrowed the combo box example for database mode while it was written as context. Measured on fresh 11.12.5 and 11.15.0 projects (Combo box 2.5.0), with `mxcli docker check --no-update-widgets`: - the reported script: CE0463 on main, 0 errors with this change; the written widget is field-for-field what `mx update-widgets` makes of it; describe -> check -> exec reports "Unchanged page" and 0 errors. - the check rules, one combo box per row: Boolean, DateTime, Decimal, AutoNumber and Binary targets are CE7247 "Only attributes of type String, Integer, Long, Enumeration are allowed here."; a target without a value attribute is CE0642 "Property 'Value' is required."; no caption is CE0642 'Caption'. check now reports exactly those, and the controls (no target, Multi, expression caption, caption by key) are clean on both. Combo box 2.6.2, which the reporter used, was not available here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J3X7yMohe1vQkLMqSGHj8e
…ties (mendixlabs#1519) alter page … { insert after dg column(Name) { column (Attribute: Kind, Caption: 'Kind') { dropdownfilter ddf (attributes: [Status]) } } } stored attrChoice "auto" with an empty `attr`, check passed, and describe printed a bare `dropdownfilter ddf` — item 2's symptom on the ALTER path, which #1422 fixed for CREATE and named as not done here. buildColumnSpecFromAST built a column's filter with BuildFilterWidget from the widget id and name alone, so no filter property was read. It now builds the filter through buildWidgetV3, as CREATE does, so the filter's definition applies. That path registers the filter's name, which exposed a second gap: a column REPLACE excluded only the target from the name scope, and ContainedWidgetNames read a column reference only as a data view footer, so a replacement reusing its filter's name was refused as a duplicate. The column REPLACE now excludes what the column contains, and ContainedWidgetNames falls back to the grid column. Measured on a fresh 11.15.0 project: INSERT then REPLACE store linked + Tmp.Item.Status, then Tmp.Item.Kind; 0 errors with --no-update-widgets; describe prints `dropdownfilter ddf (Attributes: [Kind])`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J3X7yMohe1vQkLMqSGHj8e
…endixlabs#1519) Item 3 of the report: `set (ColumnWidth: manual, Size: 220)` made the other columns collapse. That is the widget's semantics, not a write defect: Data grid 2's columnWidth getter (Datagrid 3.4.0, Datagrid.mjs) renders manual as `${size}fr`, autoFill as `1fr` and autoFit as `minmax(<minWidthLimit>px | min-content | auto, auto)`, so Size: 220 takes 220 shares against one per autoFill column. `mxcli syntax page column`, both quick references and the create-page skill called Size pixels (the syntax example was `Size: 150`). They now say it is a weight, use `Size: 2` in the examples, and document the pixel option — `ColumnWidth: autoFit, minWidth: manual, minWidthLimit: N` — which writes, round-trips and builds at 0 errors on 11.15.0. The other half of item 3 (switching back to autoFill gave CE0463) was fixed in #1422. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J3X7yMohe1vQkLMqSGHj8e
…dixlabs#1519) Item 1 of the report — `column (Caption: '', ShowContentAs: customContent)` gave CE0463 on v0.26.0 — no longer reproduces: d152835 (#1125) writes the empty header template Studio Pro writes, and its unit test covers `column (Caption: '')`. This adds the reporter's shape as an MDL regression case. Measured on a fresh 11.15.0 project with --no-update-widgets: 0 errors with main; a binary built at d152835^ reports CE0463 at Data grid 2 'dg' on the same script. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J3X7yMohe1vQkLMqSGHj8e
…xlabs#1543) `LOG ERROR NODE 'X' 'failed' WITH STACKTRACE;` was a parse error ("mismatched input 'stacktrace' expecting '('"), so every log written through MDL stored IncludeLatestStackTrace = false, an error handler could not log the trace, and describe dropped a box ticked in Studio Pro on the round trip. The model field, the modelsdk writer and the reader already carried the flag; only the language surface and the --mcp map were missing: - grammar: `logStackTrace: WITH STACKTRACE` after the template parameters (`WITH (` vs `WITH STACKTRACE` is decided on the second token); STACKTRACE is in the keyword rule, so `$latestError/Stacktrace` (System.Error's attribute) still parses - visitor, AST, builder: LogStmt.IncludeLatestStackTrace -> LogMessageAction.IncludeLastStackTrace - describe prints ` with stacktrace` only when ticked (unticked is what an absent clause builds), so existing describe output is unchanged - MCP backend sends includeLatestStackTrace when ticked No version gate: the Model SDK's LogMessageAction.versionInfo has no entry for includeLatestStackTrace. Measured on 11.12.4: mx check reports 0 errors with the flag in a microflow and a nanoflow (control: a nanoflow log with an undefined template variable reports CE0109 on that activity). Control: with only the AST field the new test fails with the reported parse error; with the grammar but no builder line it fails "IncludeLatestStackTrace = false, want true". Mirror: #1441. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YV8Q5TCsXSkkDqf2Sku4qr
…bs#1139) mendixlabs#1139 asked for Studio Pro's "Disable activity" in MDL. It is `@excluded` on the statement, and since mendixlabs#1328 the flow builder keeps it on activities in microflows and nanoflows (re-verified on 11.12.4: the reporter's repro now describes back with @excluded and stores Disabled = true). Two gaps remained: - Only ActionActivity has Disabled (Model SDK: ActionActivity.disabled, on no other type), so `@excluded if $b then ... end if;` -- or on a loop, while, return or raise error -- passed check and exec and was dropped; the branch the author meant to switch off still ran. Check now warns MDL095 (a warning, as MDL042 is for the same drop shape of @caption on a loop), from checkUnknownAnnotations so it covers microflows, nanoflows and error-handler bodies. - `mxcli syntax microflow layout` said @excluded is a DOCUMENT annotation that does not go on a statement. It now documents both meanings; the write-microflows skill links a "Disabled activities" section in reference/control-flow.md. Control: with the rule ID but no check, every case of the new test fails "want one MDL095, got []". Mirror: #1282. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YV8Q5TCsXSkkDqf2Sku4qr
…tion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LCd38DLXnG1FLJGs1eM6LD
fix: pluggable-widget-engine — combo box database mode, ALTER column filters, column Size docs (mendixlabs#1583, mendixlabs#1519)
The file was gofmt-clean. The local `make lint` that flagged it ran /usr/local/go/bin/gofmt, an older install than the go1.27.3 toolchain `go` switches to (GOTOOLCHAIN=auto), and the two disagree on this file; CI's go1.27.3 fmt-check then rejected the "fixed" version. This restores the base content. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SLbjUJghMMwekH4y5VEtBZ
…2nnrm # Conflicts: # mdl/executor/widget_engine.go
…ues-detxhx fix: log ... with stacktrace, and warn when @excluded lands on a decision or loop
A combo box whose options come from a database source (Studio Pro "Source: Database") had no mode in the definition. Its data source and item selection were "recognized but not yet persisted" (MDL-WIDGET06), describe printed the source as the association mode's `DataSource:`, and exec rebuilt TestApp's two such combo boxes as context-source, single-selection ones: mx check 11.14.0 CE0642 x4 and CE0115 x2 (a list parameter fed a single selection). The definition gains a database mode, selected by optionsSourceDatabaseDataSource: it writes source 'database', the data source and the item selection (`Selection:` or the property's own key, default Single), and the caption/value attributes now bind against that source's entity instead of the enclosing one. describe prints a database-source combo box by those keys. The example generator no longer reads the new mode's constants, as the validator never does for a widget not built in it. Rebuilt from the new description, the two TestApp pages build at 0 errors; a fresh 11.13.0 project round-trips byte-identically, and #1488's own script builds at 0 errors where it was CE0463. Refs #1647, #1488 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jEcJZDio1jrTrWtVzagjY
…content `create or modify` of a page whose combo box the statement changes rebuilt the combo box from its template and deleted its custom content, which MDL cannot author, while the content type stayed 'yes': "Replaced page", then mx check CE0642 "Custom content is required". An unchanged combo box survives through the pluggable passthrough. When the passthrough declines a stored combo box that holds custom content and the rebuild is a combo box again, exec refuses, naming the widgets: change it with `alter page … set` (which keeps the content), or drop the content first and write the combo box without its content type. check -p refuses the same rewrite up front, next to the #1622 guard. Measured on 11.13.0: unchanged → "Unchanged page"; changed → refused by both, nothing written; the remedy → 0 errors. The describe note says so. Refs #1648 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jEcJZDio1jrTrWtVzagjY
Resolves the CHANGELOG conflict: v0.28.0 was released in between, so this branch's entry moves to the new [Unreleased] section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LCd38DLXnG1FLJGs1eM6LD
CHANGELOG.md conflicted: main cut [0.28.0] and its newest fixes landed in that section's Fixed list, where this branch's entry also sat. The fix is not part of 0.28.0, so its entry moves under [Unreleased] / Fixed; main's side of the hunk is kept as is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SLbjUJghMMwekH4y5VEtBZ
fix: misleading diagnostics — MDL031 on CASE columns, and a parenless routine header
…2nnrm # Conflicts: # .claude/skills/mendix/write-microflows/SKILL.md
fix: write and describe a pluggable text-template parameter across an association (CE1365)
…-trip-gaps-ibgvit main fixed the combo box's database mode for mendixlabs#1583 (#1488) while this branch fixed it for #1647. The two converged on the same mode switch; main's version is kept whole, as it also lifts the editorConfig else-chain and resets hidden properties of another mode, which this branch did not. Resolution: main's combobox.def.json, widget_engine.go, widget_describe.go, cmd_pages_describe_bykey.go, cmd_pages_describe_pluggable.go, widget_registry_test.go and the skill reference; this branch's duplicate tests dropped; #1563's hidden-content read kept in cmd_pages_describe_parse.go. The definition had auto-merged into two database modes with no conflict marker. Re-measured on the merge: TestApp's two database combo boxes, rebuilt from their description, build at 0 errors (mx check 11.14.0), so #1647 is fixed by main's commit; the #1647 finding and bug-test now say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jEcJZDio1jrTrWtVzagjY
CHANGELOG.md conflicted again: both sides added an entry to [Unreleased] / Fixed. Both are kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SLbjUJghMMwekH4y5VEtBZ
fix: alter entity add event handler adds a second handler for the same event
fix: silent-property-drop cluster — show page pages-to-close, selection by widget key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs
ako/mxcli:maininto upstream: 27 commits from fork PRs ako#1655–ako#1661. They work through seven clusters on the fork's triage board, one commit per defect. Each has a test that fails with the reported symptom when its fix is reverted. Two of those commits are a gofmt and its revert, which net to nothing.Fixes #1139, #1250, #1494, #1495, #1514, #1519, #1540, #1543, #1583, #1617, #1618, #1628 and #1631.
describe → exec round trips on pages (#1628, #1631)
On a Studio Pro-authored 11.14 app, describe → check over all 68 pages gave 16 CE1571 reports on pages mx check passes. This brings it to 0.
UserList = $grid2, and exec had no way to write it back.Variable {Widget}, and ALTER resolves widget names too.alter page replacethat would carry hidden content onto another entity is refused (alter page replace of a combobox silently keeps the old combobox's custom content, which describe never shows (mx check CE1365) #1631). Its message names the widgets and the remedy.create or modifythat would delete a changed combo box's content is refused. That used to give CE0642.-- NOT SHOWN:comment.Pluggable widgets (#1583, #1519, #1494, #1495, #1618)
Sizeis a relative weight, not pixels.legendParams: ({1} = Repro.Parent_Child/Label)passed check and exec, then failed with CE1365. describe printed it bare, which re-ran as CE1613. The fix covers all three serializer callers: widget-level templates, object-list item templates and Data grid 2 column templates.itemSelection: Singlewritten by its widget key is stored as a plain value, so the grid has no selection #1618), for exampleitemSelection: Single.Microflows (#1543, #1139, #1617)
log … with stacktracesets "Include latest stack trace" (MDL: LOG cannot set 'Include latest stack trace' #1543). Every LOG written through MDL used to store false.log error node 'X' 'failed: {1}' with ({1} = $latestError/Message) with stacktrace;.$latestError/Stacktracestill parses.@excludedlands on a decision, loop or event (MDL syntax to disable/enable individual activities in microflows and nanoflows #1139).Domain model (#1540)
alter entity add event handlercan add a second handler for the same event.add … if not existschecks for that exact handler.drop event handler … call Mod.Mfnames which handler to drop. Without it, a drop that matches several handlers is refused.Diagnostics (#1250, #1514)
String(200)where Mendix derivesString(8).Docs
silent-property-dropwiki page is synced, and the changelog has entries for the text-template parameter fixes