From d795b78fbc3b36416af9421807e94b19109b8e8b Mon Sep 17 00:00:00 2001 From: MendixMau Date: Thu, 15 Oct 2026 22:33:03 +0800 Subject: [PATCH] learn(bug-logs): six BUG-DRAFT ledger entries from a five-app lab report (TK-027 to TK-036) check expression gaps, declare/retrieve partial checks, microflow splice and alter variable scope, create without commit, DataGrid 2 writes, describe round trip and DateTime localization. Workarounds recorded, none filed. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 1 + bug-logs/mxcli-bugs.md | 48 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e238acd..5aa8736a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m ## Unreleased +- learn(bug-logs): **six BUG-DRAFT entries from a five-app lab project (mxcli v0.26.0, Mendix 11.15)**: `check` expression gaps (formatDecimal, Decimal toString, raw backslash in replaceAll), declare/retrieve partial checks, microflow splice and alter variable scope, create without commit, Data grid 2 write defects, describe round-trip and DateTime localization. Each gives the workaround; none is filed upstream yet, upstream issue numbers named where they exist (#580, #1489, #1111, #891). Read on demand through `bin/bug-lookup.sh`. — MendixMau, five-app lab report TK-027 to TK-036 - new(mxpatch, exec): **`project-bin/mxpatch.py`, the shared patch core, and a `mxcli fix hashes` check around every `exec.sh --patch` run: the two shipped workflow patchers no longer leave a stale ContentsHash.** mxpatch finds a unit by type + name (+ module) with a byte pre-filter, finds an element by Name, gets/sets a value by key, and writes the unit and its `.mpr` ContentsHash (base64 SHA-256 of the file) in one step; dry run by default, `already applied` on a re-run, and a refusal (exit 3) when the current value is not the expected old one. `wf-set-call-captions.py` and `wf-add-path-terminators.py` now write through it, refuse drift (a caption is replaced only while it is still the stamped microflow name or the `--expect-caption` value; `--expect-paths N` for terminators), and also take the `exec.sh --patch` form (` Module.Workflow`). The index is committed before the file swap, so a kill mid-write leaves a MISMATCH that `fix hashes` reports and a re-run repairs. `mxunit_bson.py` reads BSON 0x09 (UTC datetime). `exec.sh --patch` runs `mxcli fix hashes` (v0.25.0+, probed via `fix --help`) before and after the script and restores the snapshot on any issue the baseline did not have, before mxbuild, which cannot see it. Field evidence: captured mxcli v0.25.0/v0.26.0 runs on a public model (`tests/wave2/fixtures/mxpatch/CAPTURE.txt`): master's patchers leave a MISMATCH, the ported ones verify clean; the hash routine agrees with mxcli on 67 of 67 mismatched and 302 matching units of a second model. Widget-shape copying and pluggable-widget properties wait on a captured page unit. Field run ([#390](https://github.com/MendixMau/mxcli-project-toolkit/issues/390), mxcli v0.26.0, macOS): PASS, and the patch repaired a ContentsHash MISMATCH an old-style `--patch` had left on the unit it rewrote. Fixes from it: the backup of a rewritten unit is kept outside `mprcontents/` (in `$MXPATCH_BACKUP_DIR`, which `exec.sh --patch` points into the snapshot it just took, else a 0700 `/mxpatch-bak-/`; refused when it resolves inside `mprcontents/`, through a symlink or another case spelling; named with pid and counter so two writes in one second keep both), no longer as an untracked `.mxunit.bak` that `git add mprcontents` would commit; the BUILD-LOG row carries the hash bracket (`hashes: baseline 1 mismatch (pre-existing), verify clean (1 pre-existing repaired by this patch's rewrite)`); and the baseline message says that a unit the patch rewrites gets a fresh hash, and to repair the others with `fix hashes --repair`. A baseline MISMATCH that is still reported on a unit the patch rewrote counts as new (restore, exit 1), not as pre-existing. — jopterhorst ([#294](https://github.com/MendixMau/mxcli-project-toolkit/issues/294), [#295](https://github.com/MendixMau/mxcli-project-toolkit/issues/295)) - learn(pipelines/mendix-mpr/samples): **three minimal mxcli repros from the native-module bug hunt, the files the upstream draft cites** (split from [#293](https://github.com/MendixMau/mxcli-project-toolkit/pull/293), 6/6). `fsm-template-9.24.2/native-bughunt/` holds CAPTURE.txt and D1–D3, which are written from scratch in a `Repro` module: `describe entity` printing `index ( desc);`, the native Repeater `content` slot, and no flow writable to a 9.24.2 project. They are the repros for U3, U2 and U14 in `bug-logs/pending-github-issues/2026-10-12-mxcli-0.26-round-trip-report.md`. The other 472 sample files of #293 had no citing reader, because the skills and Rehost splits state their field results inline, so none of them ships. — MendixMau, Decompose/Rehost lab runs 2026-10-12 - learn(inbox, pending-github-issues): **ten field-note drops from the Decompose/Rehost lab runs, and one not-filed draft of 53 mxcli 0.26 defects for mendixlabs/mxcli** (split from [#293](https://github.com/MendixMau/mxcli-project-toolkit/pull/293), 5/6). `contrib/inbox/2026-10-1{2,3}-*.md`: increments 1–8 of the split-a-monolith runs on a public Marketplace template (FSM 9.24.2), the native-module bug hunt, and the GenAI Showcase regeneration (0.26.0 and the 2026-10-13 nightly); each now has the template's front matter and is at most 600 words. `bug-logs/pending-github-issues/2026-10-12-mxcli-0.26-round-trip-report.md`: the U1–U53 table the inbox drops refer to, marked DRAFT — NOT FILED, to be split into one issue per defect and retested before anything is posted. No BUG numbers assigned; triage promotes. — MendixMau, Decompose/Rehost lab runs 2026-10-12/13 diff --git a/bug-logs/mxcli-bugs.md b/bug-logs/mxcli-bugs.md index f2042415..7450876f 100644 --- a/bug-logs/mxcli-bugs.md +++ b/bug-logs/mxcli-bugs.md @@ -7044,3 +7044,51 @@ Both flagged flows are Data grid 2 datasources on pages in the same module and w **Toolkit side:** do not rename the flow or add a fake caller. Accept the rise with `bin/lint-gate.sh --update-baseline --reason "QUAL004 DS_ datasource false positive (BUG-DRAFT-qual004-dg2-datasource)"`. `skills/lint-that-actually-runs.md` → "Stock rules against the toolkit's own conventions". **Expected:** a `DataSource: microflow X` on any widget, pluggable or not, is an inbound reference to X. `describe page` already prints it. + +## BUG-DRAFT-check-expression-gaps: `check` passes `formatDecimal($d, 2)`, `toString` of a Decimal into a bounded String and a lone backslash in `replaceAll`; each fails at mxbuild or at runtime (2026-10-15) + +> **NOT YET FILED.** Upstream: tracking issue mendixlabs/mxcli#580 (expression type checking, open). Draft text kept outside the repo. + +**Version:** mxcli v0.26.0 (retested on v0.27.0 where noted), Mendix 11.15, from a five-app lab project. **Reproducible:** yes on v0.27.0 with `check` alone: all three print "Syntax OK". (`upperCase()` is now caught by MDL044.) +**What happens.** (1) `formatDecimal` needs a String pattern as second argument: CE0117 at mxbuild, the most common code in the field log. (2) `toString(minutesBetween(a, b))` or `toString(x div 60)` into a String(10..40) attribute produced 43 characters at runtime and overflowed it; assigning a Decimal to an Integer is caught (MDL041) but this is not. `secondsBetween(due, now)` is absolute, so a past due date read as time left. (3) MDL string literals are raw and `replaceAll` is a regex replace: `replaceAll($s, '"', '\\"')` is stored unterminated and fails at runtime; check and mxbuild both pass it. Also seen: `Body: template '{}'` needs `'{{}}'` (CE0712), and `[%CurrentDateTime%]` in some XPath positions (CE0161). +**Toolkit side (workaround):** `formatDecimal($d, '#,##0.00')`; wrap Decimal in `floor()` before `toString`; negate `secondsBetween` when end < start; a JSON escape through `replaceAll` needs the four-backslash and eight-backslash literals; `'{{}}'` for a literal empty JSON object; declare `$Now` first instead of a date function in XPath. Money as a String attribute only when the sub-unit is fixed. Treat `check` as syntax plus a few type rules, never as the build. + +## BUG-DRAFT-microflow-declare-and-retrieve-check: a many-to-one list retrieve passes `check` and fails mxbuild; MDL043 says "object variable" for an enumeration declare; declare-then-create is MDL063 (2026-10-15) + +> **NOT YET FILED.** Related upstream: #199 (open, retrieve by association), #1422 (closed). Not retested on v0.27.0 (needs a project). + +**Version:** mxcli v0.26.0 (retested on v0.27.0 where noted), Mendix 11.15, from a five-app lab project. +**What happens.** `retrieve $L from $obj/Assoc` where the association is many-to-one seen from the one side passes `check --references` and fails in mxbuild. `declare $X Mod.Enum;` gets MDL043 worded for an object variable. `declare $X Entity = empty;` followed by `$X = create Entity (...)` is MDL063 (duplicate variable). +**Toolkit side (workaround):** list from the many side: `retrieve $L from Mod.Line where Mod_Assoc = $obj`. Enumerations: `declare $X Enumeration(Mod.Enum) = empty;`. A conditional object: a sub-microflow that returns the created object on each branch, never declare-then-create. Lists: `create list of Mod.Entity`. + +## BUG-DRAFT-microflow-splice-and-alter-scope: `create or modify microflow` refuses to splice when a loop body, a used return value, an earlier alter or an error handler changed the flow; `alter microflow` resolves a replacement against the stored flow so a variable declared in the same block is "not declared" (2026-10-15) + +> **NOT YET FILED.** Upstream: #1489 (open, error-handler activity), #1361 and #1408 (closed; #1408 makes exec all-or-nothing from v0.27.0). The alter-scope part has no upstream issue found. + +**Version:** mxcli v0.26.0 (retested on v0.27.0 where noted), Mendix 11.15, from a five-app lab project. Related ledger entry above: the splice free-room refusal that `check` does not predict. +**What happens.** "this change cannot be spliced into the stored flow: the Loop ... changes inside its body", "cannot be spliced ... $Code is still used by", and a refusal once another script had spliced a decision in. On v0.26.0 a first partial apply left the model half changed and the next `alter` failed with "no free room for the fragment" (the all-or-nothing rollback arrived in v0.27.0, not re-verified here). In one alter block, `insert after $X begin declare $Late ...; end;` then `replace loop ...` using `$Late` passes `check` and fails exec with "variable 'Late' is not declared"; re-running the script is refused (MDL090). +**Toolkit side (workaround):** add a new microflow and repoint the caller (the old flow stays unused); drop and recreate when nothing references it; `alter microflow ... insert after commit $X begin ... end` for additions; split one alter script into two blocks, declare in the first; snapshot before exec (`bin/exec.sh` already restores on a failed gate). + +## BUG-DRAFT-microflow-create-without-commit-silent: a `create` activity with no `commit` writes nothing and nothing says so (2026-10-15) + +> **NOT YET FILED.** No upstream issue found; ask is a lint rule. Verified on v0.27.0: `check` passes, no warning. + +**Version:** mxcli v0.26.0 (retested on v0.27.0 where noted), Mendix 11.15, from a five-app lab project. +**What happens.** An after-startup seed did `$o = create Mod.Item (...)` twenty times without `commit $o`. `check` passed, the log said "Seeded 20", the table held 0 rows. +**Toolkit side (workaround):** write `commit $o` on the create (or `create ... commit`) and verify with a row count, never with the log line. + +## BUG-DRAFT-dg2-write-defects-field: Data grid 2 `Caption: ''` with `customContent` (CE0463), `dropdownfilter` loses its attribute, `SET ColumnWidth: manual` collapses the other columns (2026-10-15) + +> **NOT YET FILED.** Upstream: #1111, #830 (closed), #891 (open). v0.27.0 changelog: "DataGrid 2 columns with no caption or no attribute get the empty templates Studio Pro writes (CE0463)" may fix the first; retest before filing. + +**Version:** mxcli v0.26.0 (retested on v0.27.0 where noted), Mendix 11.15, from a five-app lab project. Related: BUG-38, BUG-42, `skills/learned-detection-gaps.md` (dropdownfilter via mxcli). +**What happens.** (1) `column (Caption: '', ShowContentAs: customContent)` passes `check`, CE0463 on the grid at mxbuild; any non-empty caption builds. (2) `dropdownfilter (attributes: [...])` writes a filter without its attribute ("Unable to get filter store", the grid blanks). (3) `SET (ColumnWidth: manual, Size: 220) ON ` makes sibling columns vanish; restoring with `autoFill` alone built CE0463 and was rolled back; `ColumnWidth: autoFill, Size: 1` was clean. +**Toolkit side (workaround):** a non-empty caption; drop the dropdown filter or build it by hand in Studio Pro; set widths in CSS (`grid-template-columns` override) instead of `ColumnWidth`. + +## BUG-DRAFT-describe-roundtrip-gaps-and-datetime-localization: `describe snippet` omits the root `DataSource: $View` (re-apply fails CE0488) and a page describe lists 37 of 40 widgets; an existing DateTime attribute cannot be switched to localized by `create or modify` or `alter` (2026-10-15) + +> **NOT YET FILED.** Upstream: none found for the entity case (#1297 and #1251 are view entities); the snippet case may be fixed by v0.27.0 (ako/mxcli#1138, data view sourced from a snippet parameter). Retest both before filing. + +**Version:** mxcli v0.26.0 (retested on v0.27.0 where noted), Mendix 11.15, from a five-app lab project. +**What happens.** The described snippet text has no `DataSource: $View` on its root data view, so exec of it fails CE0488. A page describe omitted a pill, a text and a link widget, so a design audit reads "partially read". A DateTime attribute created `not localized` keeps that after `create or modify entity` and after `alter ... modify attribute X: DateTime`; only writing `DateTime localized` flips it. `not localized` makes the client compare the UTC wall clock with local now, so overdue chips were wrong. +**Toolkit side (workaround):** after a snippet round trip add the datasource by hand; count widgets in the described text against the page before trusting an audit; always write `DateTime localized` explicitly, then `describe entity` to read it back.