You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit fa0dc4f
Browse filesBrowse the repository at this point in the historyBrowse files
fix(check): catch five script shapes that passed check --references
Each of these passed `mxcli check -p app.mpr --references` and then failed
at exec or at mxbuild (reported from the marketplace-rnd project):
- XPath `[Module.Assoc != empty]` / `= empty` (CE0161): MDL047 now covers
associations, with a path-form hint.
- retrieve over a Reference from its TO end (owner not Both) whose result
is used as an object (CE0117): reported with a head()/limit 1 hint.
- page layout that does not exist: resolved against the project and the
script's CREATE LAYOUT statements.
- page/snippet widget action naming a microflow created later in the
script: MDL-ORDER01 now walks widget actions.
- CALL MICROFLOW/NANOFLOW with unmapped parameters (CE0115) or a string
literal for an enumeration parameter (CE0117). The microflow type builders
now set ExplicitEnum for `enum M.X` / `Enumeration(M.X)`, which they
never did.
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .claude/skills/fix-issue/findings/mdl-executor.jsonl
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -680,3 +680,4 @@
680
680
{"area": "mdl/executor", "date": "2026-09-23", "symptom": "`describe page` on a page with several galleries emits MDL that mxcli's own `check --references` rejects: `duplicate widget name 'template1' (used 4 times) — Mendix requires unique widget names per page (CE0495)` (and `filter1` when the galleries have filters). The row/col half of the same report was already fixed; this third name survived it", "cause": "`template`/`filter` inside a gallery are CHILD SLOTS of its definition (gallery.def.json childSlots). `applyChildSlots` builds only the block's children into the slot property and discards the block's name, so DESCRIBE has to synthesise `template1` for every gallery. `checkDuplicateWidgetNames` already exempted the parent's object-list containers but not its child-slot containers", "file": "`mdl/executor/validate_page_context.go` (`unstoredContainerKinds`, was `objectListContainerKinds`; `checkDuplicateWidgetNames`); test `mdl/executor/validate_page_slot_containers_test.go`", "insight": "**When a multi-symptom report is marked fixed, re-run every symptom in it, not the first** — the earlier fix covered `row1`/`col1`/`FullName` and its test never mentioned `template1`, so the issue stayed open with a third name nobody had reproduced. Cheapest proof a name is not stored: author a distinctive one (`template contentZebra`), `grep -rl` it in `mprcontents/` (0 files) and DESCRIBE it back (`template1`). Don't exempt the keyword `template` globally — outside a slot-declaring widget, `template` is `buildTemplateV3`, a `Forms$DivContainer` that DOES store its name; resolve it from the enclosing widget's def (both `ChildSlots` and every mode's), and cover the `container <slotName>` spelling that `applyChildSlots` routes by name. Measured on 11.12.2: four galleries each `template template1` → `mx check` 0 errors", "refs": ["mendixlabs/mxcli#978"], "ce": ["CE0495"]}
681
681
{"area":"mdl/executor","date":"2026-09-23","symptom":"\"List views are written with `Editable: false` by mxcli, so every input inside a list view renders disabled — even with `editable: Always` on the text box, and even inside a nested data view.\" Valid BSON, `mxcli check` clean, build succeeds; only the rendered app shows it","cause":"Not a writer bug: false IS Mendix's default for Pages$ListView.editable. The 2026-09-06 fix made an explicit `editable: true` reach the document, but nothing told an author who never wrote it that the list view's read-only context overrides the inputs' own `editable:`","file":"`mdl/executor/validate_listview_editable_inputs.go` (MDL-WIDGET31, hooked in `validate_widgets.go`); test `validate_listview_editable_inputs_test.go`; example `mdl-examples/bug-tests/631-listview-inputs-not-editable.mdl`","insight":"**Measure the default before changing it — and the measurement is cheap.** The issue parked \"default to true\" on a Studio Pro comparison it could not run; `npm pack mendixmodelsdk` and reading the class in `src/gen/pages.js` settles it in a minute: `new PrimitiveProperty(ListView, this, \"editable\", false, …)` and `_initializeDefaultProperties` never sets it, so flipping the default would have made mxcli disagree with every Studio Pro-authored list view. A Studio Pro project confirms it (ako/TestApp, 11.14.0): 30 of 32 list views stored false, none holding an input, and the one with inputs set to true by its author; `describe` of that page checks clean, deleting `Editable: true` from it fires MDL-WIDGET31, and describe -> exec preserves it. The fix is therefore a check for the COMBINATION (not-editable list view + input not marked `editable: Never`). Read editability with the SAME accessor the builder uses (`GetBoolProp`): a quoted `editable: 'true'` parses as a string, the builder writes false, and a rule that read it leniently would stay quiet on a page that renders disabled. Stop the descent at a nested list view — its own Editable governs its inputs and it is visited on its own — but NOT at a nested data view, which the reporter measured does not escape the context","refs":["ako/mxcli#631"],"rules":["MDL-WIDGET31"]}
682
682
{"area": "mdl/executor", "date": "2026-09-23", "symptom": "`captionparams` on an action button is accepted by `mxcli check` but not written; a container with `onclick` and a dynamic text does the job. Measured: `actionbutton b (caption: 'Save {1}', captionparams: [{1} = Title])` in a dataview wrote the LITERAL 'Title' (describe: `ContentParams: [{1} = 'Title']`), check --references and mx check both clean; and describe -> exec of any button with params dropped them all -> 4x CE0720 'Place holder index 1 is greater than 0' at mx check.", "cause": "buildButtonV3 carried its own copy of the template-parameter resolver (bare name without `.`/`$` -> quoted literal) instead of the shared buildClientTemplateParams that dynamictext/datagrid columns use; and DESCRIBE emitted a button's params as `ContentParams:`, a key the button builder never read. MDL-WIDGET04's orphan-placeholder check covered dynamictext only, so the round-tripped `{1}` with no parameter reached the build.", "file": "`mdl/executor/cmd_pages_builder_v3_widgets.go` (buildButtonV3 -> buildClientTemplateParams, ContentParams fallback), `mdl/executor/cmd_pages_describe_output.go` (ActionButton emits CaptionParams), `mdl/executor/validate_widgets.go` (validateButtonCaptionPlaceholders)", "insight": "**The report's workaround is the diagnosis**: 'a dynamic text does the job' means the SAME parameter text works on one widget and not another, so diff the two builders before touching grammar or the writer -- the writer was fine (clientTemplateToGen is shared). Two duplicate resolvers had drifted: the shared one gained SourceVariable, toString, association steps and format blocks over a year of fixes; the button copy got none. Do not trust 'check passed' for the literal case -- a literal holding the attribute's name is a valid model, so nothing short of describe (or looking at the rendered button) shows it. The describe->exec round trip is the cheap detector: run it once and the ContentParams/CaptionParams mismatch drops every param and mx check reports CE0720. Keep reading `ContentParams:` on buttons -- scripts dumped before this fix use it. Remaining gap, NOT this bug: `check --references` does not flag an unknown BARE attribute in contentparams/captionparams on either widget (`[{1} = Titel]` passes).", "refs": ["ako/mxcli#632"], "ce": ["CE0720"], "rules": ["MDL-WIDGET04"]}
683
+
{"area": "mdl/executor", "date": "2026-09-23", "symptom": "`mxcli check script.mdl -p app.mpr --references` printed \"Check passed!\" for five scripts that then failed at exec or at mxbuild (marketplace-rnd): (1) XPath `[UserGroups.Group_Guests != empty]` gives CE0161; (2) `retrieve $G from $App/UserGroups.GuestGroup_App`, which starts at the TO end of a Reference, gives a list, and using `$G/UUID` as an object gives CE0117; (3) `Layout: Atlas_Core.Popup_Content`, a layout that does not exist, makes exec fail with 'layout not found'; (4) a page button whose `Action: MICROFLOW` names a microflow created later in the script makes exec fail midway; (5) a string literal passed to an enum parameter gives CE0117, and unmapped call parameters give CE0115", "cause": "Five holes in the check tiers, none of them a writer bug. The XPath hint table covered `= empty` on attributes but not on associations. No rule compared a retrieve's start entity with the association's ends, because the flow builder silently types the output from how it is used. CreatePageStmtV3 validation resolved widgets but never the layout. MDL-ORDER01's eager-reference walk covered flow bodies but not widget actions. validateFlowArguments checked data-source calls only, never CALL MICROFLOW/NANOFLOW activities, and flowParam did not record enum types. A sixth, found only on a real parse: the microflow-context type builders in `mdl/visitor/visitor_microflow.go` built `enum M.X` / `Enumeration(M.X)` without ExplicitEnum, so any check keyed on a certain enum was silent for microflow parameters", "file": "`mdl/executor/validate_microflow.go` and `validate_widgets.go` (xpathAssocEmptyMatch, MDL047); `validate_reverse_reference_retrieve.go`; `validate.go` (pageLayoutResolves); `validate_definition_order.go` (widgetFlowDefRefs); `validate_flow_call_args.go` plus flowParam.Enum in `validate_datasource_args.go`. Examples: `mdl-examples/bug-tests/check-gap-*.mdl`; `mdl/visitor/visitor_microflow.go` (ExplicitEnum on both enum branches, test `visitor_microflow_enum_param_test.go`)", "insight": "**Run the reporter's failing script through the released `check --references` before writing any rule.** v0.23 passed all five, which proved each was a check gap rather than a bad install. Three of the five cannot be judged without the model: the association's ends and owner, the layout list, and the callee's signature. Those rules therefore live in the `--references` tier, and their bug-test scripts are plain `.mdl` that fail only with `-p`. Naming them `.fail.mdl` would make check-mdl report a working rule as regressed (#891/#892). For the reverse-retrieve rule, owner Both means one-to-one, so the TO-side result is an object and must not be flagged. `collectObjectInputVariables` does not look at DECLARE initial values, which is exactly where the report used the variable, so the rule adds that scan itself. For the enum-literal rule, only an explicit `enum Module.Name` parameter is trusted, because a bare `Module.Name` parses as TypeEnumeration whether it is an entity or an enum. Known skips: associations the script creates itself (case 2), and string variables passed to enum parameters, since their type is unknown at that point. **Test the rule through `visitor.Build`, not only on hand-built AST.** The enum-literal unit test passed on an AST with ExplicitEnum set by hand, but the real script never produced that flag, so only the end-to-end run against the project exposed it", "refs": ["marketplace-rnd"], "ce": ["CE0161", "CE0117", "CE0115"], "rules": ["MDL047", "MDL-ORDER01"]}
"page '%s' references layout '%s', which does not exist in the project or this script. List the layouts with `show catalog table layouts` (e.g. Atlas_Core.Atlas_Default, Atlas_Core.PopupLayout).",
636
+
s.Name.String(), s.Layout)
637
+
}
612
638
// Every widget-bearing field, not just the bare body — see pageWidgets.
0 commit comments