Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
867c4dc
fix(check): stop false MDL-WIDGET07 on builder-read widget properties
ako Oct 8, 2026
900d4e6
fix: double apostrophes in menu captions written by describe navigati…
claude Oct 8, 2026
902ffe2
fix: describe nanoflow emits its grant execute line (mendixlabs/mxcli…
claude Oct 8, 2026
9db0be2
fix: describe subcommand accepts published REST services (#1347)
claude Oct 8, 2026
de538c5
fix: store a restrict association's delete message in the project lan…
claude Oct 8, 2026
f2b7982
Merge pull request #1062 from ako/fix/1346-widget07-showfooter
ako Oct 8, 2026
baa3a2b
Merge branch 'mendixlabs:main' into main
ako Oct 9, 2026
9ed928f
fix: describe auto-detect finds documents without a catalog
claude Oct 9, 2026
7dffdb8
fix(run-local): apply domain model changes under --watch on Windows
Oct 9, 2026
7a2b535
build: move to Go 1.27.2 and golang.org/x/net v0.60.0 for govulncheck
claude Oct 9, 2026
fb951ce
build: keep mdl/exprcheck/parser.go gofmt-clean under Go 1.26 and 1.27
claude Oct 9, 2026
cd19fbf
Merge pull request #1064 from ako/claude/mxcli-issue-1343-h33sf6
ako Oct 9, 2026
233036f
Merge remote-tracking branch 'origin/main' into claude/mxcli-issue-13…
claude Oct 9, 2026
05dcc08
Merge remote-tracking branch 'origin/main' into claude/mxcli-issue-13…
claude Oct 9, 2026
b8f5ebd
Merge remote-tracking branch 'origin/main' into claude/describe-autod…
claude Oct 9, 2026
07a9216
build(deps-dev): Bump handlebars
dependabot[bot] Oct 9, 2026
18f7fbf
chore(mpr): delete the dead security_patch reconciler
ako Sep 25, 2026
336ed81
Merge remote-tracking branch 'origin/main' into claude/mxcli-issue-13…
claude Oct 9, 2026
d5c08ba
fix(check): resolve a module role's module before exec does (mendixla…
claude Oct 9, 2026
8a4a906
docs: fmt --help and test-microflows skill say test files take the md…
claude Oct 9, 2026
083352d
fix(check): resolve a script set's files against what the earlier one…
claude Oct 9, 2026
11fd49d
fix(skills): gate whole skill examples on mxcli check; fix three that…
claude Oct 9, 2026
1f2841c
docs(skills): correct OR REPLACE, folder placement and CE0463 advice
claude Oct 9, 2026
2088265
Merge pull request #1065 from ako/claude/mxcli-issue-1345-5o9af9
ako Oct 9, 2026
5f9125a
Merge pull request #1063 from ako/claude/mxcli-issue-1344-gbs17m
ako Oct 9, 2026
1cd8587
Merge pull request #1067 from ako/claude/describe-autodetect-no-catalog
ako Oct 9, 2026
4bba853
Merge pull request #1072 from ako/claude/optimistic-mccarthy-ivluu6
ako Oct 9, 2026
da2d7aa
Merge pull request #1070 from ako/claude/mxcli-issue-1347-2nty2v
ako Oct 9, 2026
5f1b099
docs(site): fix examples that fail mxcli check or mxbuild; gate docs-…
claude Oct 9, 2026
d2f9f5b
Merge pull request #1071 from ako/claude/kind-darwin-bpf3n3
ako Oct 9, 2026
f736207
Merge pull request #1066 from ako/fix/security-patch-owner-keys
ako Oct 9, 2026
41b6dd0
fix(odata): don't carry a member's CanBeEmpty across a change of key …
claude Oct 9, 2026
2932f2d
docs(site): an OData key needs UNIQUE only; correct the CE0309 attrib…
claude Oct 9, 2026
169bd66
Merge pull request #1069 from ako/dependabot/npm_and_yarn/dot-claude/…
ako Oct 9, 2026
3dfd7ee
Merge pull request #1073 from ako/claude/serene-carson-crj06x
ako Oct 9, 2026
4b24a94
Merge remote-tracking branch 'origin/main' into fix/1342-windows-webd…
Oct 9, 2026
e54bcf7
Merge pull request #1068 from ako/fix/1342-windows-webdir-locked
ako Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/skills/debug-bson.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ for t, props in crash_props.items():

**Investigation methodology used for v0.10 CE0463 fixes** — see [WIDGET_BSON_VERSION_COMPATIBILITY.md](../../docs/03-development/WIDGET_BSON_VERSION_COMPATIBILITY.md) for the full case study and version-resilience model.

**Quick workaround** (if you can't fix the root cause): normalize with `mxcli docker check`/`build`, which run the widget update **and preserve MPRv2 storage** (they snapshot/restore `.mpr` + `mprcontents/`). Do **not** run bare `mx update-widgets` on a v2 project you care about — it converts to single-file v1 and deletes `mprcontents/` (corrupts git, breaks `mxcli run --local`). Raw `mx update-widgets` is fine only on a throwaway diagnostic copy or a v1 project.
**Quick workaround** (if you can't fix the root cause): normalize with `mxcli fix widgets -p app.mpr`, which runs the widget update on the project **and preserves MPRv2 storage**. Not `mxcli docker check`/`build`: they run the update on a **temporary copy**, so a CE0463 the normalization clears is not reported while the stored project still fails MxBuild — use `docker check --no-update-widgets` to see the project as stored (and [`diagnose-ce0463.md`](./diagnose-ce0463.md) before calling it widget drift). Do **not** run bare `mx update-widgets` on a v2 project you care about — it converts to single-file v1 and deletes `mprcontents/` (corrupts git, breaks `mxcli run --local`). Raw `mx update-widgets` is fine only on a throwaway diagnostic copy or a v1 project.

### CE0642: Property X Is Required

Expand Down Expand Up @@ -440,7 +440,7 @@ for _, pm := range a.ParameterMappings {

2. **Mode-dependent properties must be consistent**: When changing a mode-switching property (e.g., `showContentAs`), all dependent properties must be updated to match.

3. **Widget normalization is the safety net — via `mxcli docker check`/`build`**: they run the update-widgets normalization *and* preserve MPRv2 storage (snapshot/restore). Bare `mx update-widgets` does the same normalization but rewrites a v2 project to v1 and deletes `mprcontents/` — only use it on a v1 project or a throwaway diagnostic copy.
3. **Widget normalization is the safety net — via `mxcli fix widgets`**: it applies the update-widgets normalization to the project *and* preserves MPRv2 storage. `mxcli docker check`/`build` normalize only a temporary copy, which hides CE0463 without fixing the stored project. Bare `mx update-widgets` does the same normalization but rewrites a v2 project to v1 and deletes `mprcontents/` — only use it on a v1 project or a throwaway diagnostic copy.

4. **The mpk is the source of truth**: The XML schema defines property types/defaults, the editorConfig.js defines visibility rules. Together they specify the complete expected Object structure.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-08", "symptom": "`mxcli describe published rest service M.Api` prints \"Unknown type: published rest service\", and auto-detect (`mxcli describe M.Api`) says no describable document is found even when the catalog lists the service, while `describe published rest service M.Api` works under `mxcli -c` / exec / the REPL", "cause": "The describe subcommand keeps its own type-keyword -> MDL DESCRIBE switch, plus two auto-detect maps (catalog ObjectType and unit $Type -> keyword), none of which had an entry for published REST services; the MDL grammar and executor did", "file": "cmd/mxcli/cmd_describe.go", "fix": "Dispatch moved into the pure describeMDLCommand(); added publishedrestservice / published rest service / restservice / rest service, PUBLISHED_REST_SERVICE and Rest$PublishedRestService", "insight": "The subcommand is a second, hand-kept copy of the DESCRIBE grammar's type list, so a new doctype in the grammar does not reach it. TestDescribeMDLCommand_AutoDetectKeywordsAccepted now asserts every auto-detect keyword dispatches and its MDL parses; it would also have caught the old maps pointing at a keyword the switch lacked. Wrong turn to skip: testing auto-detect without a catalog — the live-reader fallback (resolveViaReader) calls ListRawUnits, which the model engine does not implement, so it finds no document of any type; that is a separate defect.", "refs": ["mendixlabs/mxcli#1347"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"date": "2026-10-08", "area": "cmd/mxcli", "symptom": "Windows, `run --local --watch` (Mendix 11.12): page and microflow edits hot-reload, but adding a persistent entity or attribute fails every rebuild with \"The process cannot access the file '...\\deployment\\web' because it is being used by another process\"; the build has emptied web/ and the app 404s until `run --local` is restarted", "cause": "The incremental rollup bundler is started with cmd.Dir = deployment/web, and Windows refuses to remove a directory that is any process's working directory. Page/microflow edits rewrite files inside web/ and are unaffected; a domain model change makes mxbuild recreate web/ itself. Killing rollup-runner by hand looked like no help because watchAndApply's EnsureAlive restarts the bundler just before the next serve build", "fix": "bundlerSupervisor.BuildReleasingWebDir wraps the watch loop's serve build: on a sharing-violation failure naming deployment/web (webDirInUse), stop the bundler, retry the build, then Restart a fresh bundler whose first build is a full bundle (so the AwaitRebuild wait is skipped). A failed retry leaves the bundler down for EnsureAlive", "insight": "Do not move the bundler's cwd out of web/ to dodge the lock: mxbuild's rollup-plugin-mendix-pages resolves page paths with path.relative(cwd, id) (see the 2026-10-02 page-glob finding), so that breaks page bundling. Retry-on-failure keeps the ~4s incremental path for page edits; stopping the bundler before every build would cost each of them a cold bundle. The Windows test proves both premises on a real process: os.Remove(web) fails with the same sharing violation while a child has it as cwd, and succeeds after WebClientWatcher.Stop. Wrong turn to skip: removing web/ straight after cmd.Start succeeds and looks like a disproof — the child takes its cwd handle during its own initialisation, after Start returns, so wait for the child to announce itself first. E2E on Windows 11 arm64: 11.13.0 (rollup.config.mjs present) with the retry disabled reproduces the report exactly (build failed on deployment\\web, then / and /dist/index.js 404); the fixed binary logs the retry and applies via restart (~26-32s, 200s after), twice in a row, and a page edit afterwards still re-bundles incrementally (reload 7.6s, gen 1->2, no bundler restart) — so nothing else (runtime JVM, Gradle daemon) holds web/. 11.12.6 does NOT reproduce: its mxbuild writes web/dist and no rollup config (planWebClient=prebuilt, no mxcli bundler), so the domain change applied on the unfixed binary — pick a version by the deployment shape, not the minor number", "file": "cmd/mxcli/docker/webclient_supervisor.go (BuildReleasingWebDir, webDirInUse); cmd/mxcli/docker/runlocal.go (watchAndApply)", "test": "cmd/mxcli/docker/webclient_supervisor_test.go; cmd/mxcli/docker/webclient_webdir_windows_test.go", "refs": ["mendixlabs/mxcli#1342"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli","date":"2026-10-09","symptom":"`mxcli check a.mdl b.mdl -p app.mpr` reported a combobox datasource in b.mdl naming an entity a.mdl creates as \"entity not found\", although `exec` on each file in order succeeds and the same statements in ONE file pass `check -p` (reported on v0.25.0, Mendix 11.12.1). On current main the page parameter's entity is reported first (\"parameter $Order of page …: entity … does not exist\"). Issue mendixlabs/mxcli#1355","cause":"runCheckFiles called runCheckFile once per file against --project as it stands; the only set-level pass was MDL-STUB01. \"References to objects created within the script are skipped\" held per file, never across the set, so every reference kind (entity, association, page, module) to an earlier file's creation failed — not just the widget datasource the report names.","file":"`cmd/mxcli/cmd_check.go` (runCheckFiles / runCheckFileAgainst / applyToScratch), `mdl/scriptdiff/scriptdiff.go` (Scratch: NewScratch / Apply / Close); test `cmd/mxcli/check_script_set_refs_test.go`","insight":"**A report naming one reference kind is the first symptom the reporter hit, not the blast radius** — the reported kind (widget datasource) was a red herring: the files were checked in isolation, so the fix belongs in the set runner, not in the widget resolver, and the reporter's \"the page parameter is not flagged\" did not hold on main. Skip the tempting fix of seeding earlier files' definitions into scriptContext: every reference pass in validateProgramWithWarnings (grants, forward refs, members, XPath, ALTER dry-runs, project conflicts) builds its own context from the program, and error messages mix `statement N:` with unprefixed text, so neither seeding nor filtering a concatenated program is faithful. Running the earlier files for real on a scratch copy (scriptdiff's copy + outsideGuard, which refuses SQL/IMPORT/foreign CONNECT) makes file N see exactly what exec leaves, for every reference kind at once. A file whose own check fails is NOT applied — exec's pre-flight would write nothing — and the output says which files the later ones were checked without. Controls in the test: wrong file order still fails, a datasource entity no file creates is still \"entity not found\", the project tree is byte-identical afterwards; with the scratch line removed the test fails with the parameter error. Repro `mdl-examples/bug-tests/1355-script-set-a-domain.mdl` + `1355-script-set-b-page.mdl`, checked together.","refs":["mdl-examples/bug-tests/1355-script-set-a-domain.mdl","mdl-examples/bug-tests/1355-script-set-b-page.mdl","cmd/mxcli/check_script_set_refs_test.go"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-09", "symptom": "fmt --upgrade adds `mdl 1;` to a .test.mdl, but fmt --help and the test-microflows skill say test files take no header", "cause": "ako/mxcli#847 made the runner and check read a test file header and made fmt --upgrade add it by default, and updated the CHANGELOG, docs-site test-formats.md and the code comment beside the branch; the fmt --help paragraph and the skill sentence describing the pre-#847 behaviour (\"takes no language header yet, so --header adds none to it\") were not touched, so the behaviour was right and the two texts an agent reads first contradicted it.", "file": "cmd/mxcli/cmd_fmt.go", "fix": "Both texts now say a test file gets the header by default and name --header=false as the way to decline it; cmd_fmt_testfile_header_doc_test.go runs the reporter file through fmt --upgrade and fails if either text again says a test file takes no header or stops naming --header=false.", "insight": "When a report pits behaviour against docs, settle which side is intended from the CHANGELOG entry that introduced the behaviour before touching code: here #847 said outright that --upgrade adds the header to test files, so the fix is text-only and changing fmt would have regressed #847. The tell for a stale sentence is the word \"yet\": a doc that says a feature does not exist yet must be grepped for when the feature lands, and a test that pins the doc to the behaviour on one input is what keeps the next such change from leaving it behind.", "refs": ["mendixlabs/mxcli#1356", "ako/mxcli#847"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/backend", "date": "2026-10-09", "symptom": "With no .mxcli/catalog.db, `mxcli describe -p app.mpr Mod.Name` (type auto-detected) reports `no describable document named \"Mod.Name\" found in the project` for a microflow, page or any other document; only entities and associations resolve, and the same command works once `refresh catalog` has run", "cause": "describe's live fallback (resolveViaReader) calls ListRawUnits on the backend.FullBackend that the root package's Open returns; *Backend never declared it, so the unimplemented stub answered with an error the fallback discards. unimplemented_reachability_test.go recorded it as an accepted BYPASS ('describe holds a concrete reader'), true before Open stopped aliasing sdk/mpr and false after", "file": "mdl/backend/modelsdk/raw_lookup.go", "fix": "Backend.ListRawUnits delegates to the codec reader (which already had it); entry removed from unreachableUnimplemented", "insight": "The reachability record is a measurement with a date, and the reason column goes stale when a caller's type changes underneath it — `scripts/backend-reachability.sh ListRawUnits` said LIVE in one run and named the call site. Re-run the probe on any entry whose reason names a caller rather than trusting the column. The symptom hid because resolveViaReader ignores the ListRawUnits error (`if err == nil`), turning 'not implemented' into 'not found'.", "refs": ["mendixlabs/mxcli#1347"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-10-08", "symptom": "`mxcli check` warns MDL-WIDGET07 \"property `showFooter` is not recognized and will be silently dropped on write\" on a dataview, yet `exec` writes it and `describe page` emits `ShowFooter: true` — so re-executing describe's own output warns too. Same false warning for `Menu:` / `Profile:` / `Orientation:` on navigationtree / menubar and `SizeMode:` on a scroll-container `region`", "cause": "`staticWidgetKnownProps` (the MDL-WIDGET07 allow-list) is hand-maintained, and its drift guard `TestStaticWidgetKnownPropsCoverDescribe` was a second hand-typed list. #813 added the builder read (`lookupPropCI(w, \"ShowFooter\")`) and the describe emission but neither list", "file": "`mdl/executor/validate_widgets.go` (`staticWidgetKnownProps`), guard in `mdl/executor/validate_widgets_known_props_1346_test.go`", "insight": "Replace the hand-typed guard with a source scan: `go/parser` over `cmd_pages_builder*.go` for `Get*Prop(\"K\")`, `lookupPropCI(w, \"K\")` and `Properties[\"K\"]`, plus the `\"K: \"` strings in `cmd_pages_describe_output.go`. Its first run found the reported key and four more nobody had reported (SizeMode is used by a checked-in example, `bug-tests/573-simple-menu-bar.mdl`). The only exclusions are `ImageUrlParams` / `AlternativeTextParams`, emitted solely for the PLUGGABLE `image` widget, which MDL-WIDGET01 validates — probing with `staticimage` instead of `image` made them look like false positives too. Issue #1346", "refs": ["#1346", "#813"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-10-08", "symptom": "`describe nanoflow` omits `grant execute on nanoflow \u2026 to \u2026;` for a nanoflow with allowed roles, so a describe -> exec round trip (or renamed copy) silently leaves it with no roles; `show access on nanoflow` lists them and `diff-local` prints the grant", "cause": "`describeNanoflow` kept its own copy of the flow renderer without the grant block that `describeMicroflowMode` and `renderMicroflowMDL` each carried as a hand-copied loop", "file": "`mdl/executor/cmd_microflows_show.go` (`describeNanoflow`, new `flowGrantLines`)", "insight": "When one doctype's output is right on one path and wrong on another, diff the renderers, not the backend: the data was read correctly (show access proved it), and the 2026-06-30 finding for the same symptom was a different cause (backend never populated roles). Three renderers for one output is the defect \u2014 the grant block is now one helper, and the test parses the describe output and asserts a GrantNanoflowAccessStmt rather than grepping for text.", "refs": ["mendixlabs/mxcli#1345"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-10-08","symptom":"`describe navigation` / `describe menu` writes a menu caption with an apostrophe unescaped (`menu item 'Customer's orders'`), so the output fails `mxcli check`/`exec` with `line 7:20 extraneous input 's' expecting {MENU_KW, '}'}` and a describe -> exec round trip loses the navigation statement","cause":"`printMenuMDL` formatted captions as `'%s'` instead of `mdlQuote`; the menu-item notes in `menuItemActionMDL` did the same. `cmd_navigation.go` was not in `TestDescribers_HaveNoHandRolledStringLiterals`' file list, so the #1006 guard never scanned it","file":"`mdl/executor/cmd_navigation.go` (`printMenuMDL`, `menuItemActionMDL`, new `menuCaptionNote`)","insight":"**The #1006 source-scan guard only covers the files on its list — a describer missing from the list is unguarded, and adding the file is the first step of any quoting fix (it listed all nine sites here at once).** Notes inside `--` comments quote with `mdl0Quote`, not `mdlQuote`: under mdl 1 a caption's line break is written verbatim and would end the comment. Prose status messages (`Navigation profile %s updated.`) switch to `mdlQuoted` rather than widening the guard's skip rule. Guard `TestDescribeNavigation_CaptionWithApostropheRoundTrips`; control: unfixed binary on testdata/testapp-views describes `menu 'Customer's menu'` and `check` fails at `line 7:17`; fixed, describe -> exec -> describe is byte-identical. Repro `mdl-examples/bug-tests/1343-navigation-caption-apostrophe.mdl`","refs":["mendixlabs/mxcli#1343","mendixlabs/mxcli#1006"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-10-08", "symptom": "`on delete restrict error message '…'` (and `delete_behavior prevent error_message`, `alter association … set on delete restrict error message`) stores the ChildErrorMessage Texts$Text with one translation whose LanguageCode is always en_US; on a project whose default language is nl_NL the app has no message in its own language when a delete is refused. `mx check` reports 0 errors", "cause": "`deleteErrorText` hardcoded `{\"en_US\": msg}`; `sdk/domainmodel.DeleteBehavior` carried the message as a bare string with no language, so the executor could not pass `authoringLanguage(ctx)` down; `deleteErrorMessageFromGen` read en_US first, so DESCRIBE, the cross-module patch's no-op compare, and the alter read-back all looked at the wrong translation", "file": "`sdk/domainmodel/domainmodel.go` (`DeleteBehavior.ErrorMessageLanguage`, `ErrorMessageTranslations`), `mdl/executor/cmd_associations.go` (create/alter set the language, `deleteMessageIn` for describe + verify), `mdl/backend/modelsdk/domainmodel_write.go` (`deleteErrorText`), `domainmodel_alter.go` (`patchCrossDeleteErrorMessage` edits one language, keeps the rest), `domainmodel.go` (read side)", "insight": "**A #970-class miss: any text carried through a semantic struct as a bare `string` has nowhere to hold its language — grep the sdk types for `string` fields that the backend turns into a Texts$Text, not for `\"en_US\"`.** Fixing the backend alone does nothing: measured on 11.12.4 with a build that had the backend change but not the executor's, the stored code was still en_US — the language must be named where `authoringLanguage(ctx)` is in scope. The read side needs every translation, not one string, or DESCRIBE and the alter read-back compare against the stale en_US that CarryTranslations keeps. Oracle is the stored LanguageCode (`strings` on the .mxunit is enough), not `mx check`. Guards `TestCreateAssociation_DeleteMessageUsesProjectLanguage`, `TestDeleteErrorMessage_StoredInTheGivenLanguage`; repro `mdl-examples/bug-tests/1344-delete-message-default-language.mdl`", "refs": ["mendixlabs/mxcli#1344", "mendixlabs/mxcli#970"]}
Loading
Loading