Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
4f2436e
fix: a decision's caption change is set in place, not refused as a pa…
claude Oct 22, 2026
94884b3
fix: splice a change to an activity with a custom error handler (mend…
claude Oct 22, 2026
b9bedb2
fix: a note restated before @position says it reads as a free note (m…
claude Oct 22, 2026
7758de0
fix: keep the notes a statement states on an activity with an error h…
claude Oct 22, 2026
6507dad
fix: git note --write loses notes when stdout's reader exits early
claude Oct 22, 2026
70fd7a0
fix: splice a note added to or reworded on a decision or an end event…
claude Oct 22, 2026
3bbbead
fix: docker check says widgets were normalised after update-widgets f…
claude Oct 22, 2026
711ba2c
docs: scope docker's 11.6.1 floor to build; check works on Mendix 10
claude Oct 22, 2026
054f48a
docs(proposal): a 1,771-call build resizes the document — tool output…
claude Oct 22, 2026
686d87a
refactor(executor): extract MDL-SET01's variable typing into flowObje…
claude Oct 22, 2026
a33c94d
fix(alter page): set (Action: …) writes a container's OnClickAction
claude Oct 22, 2026
c2b5fa5
refactor(catalog): read a widget's click action from types.WidgetClic…
claude Oct 22, 2026
40e45d1
docs(skills): keep write-microflows under the 700-line body limit
claude Oct 22, 2026
3ca9a7f
fix: check predicts a flow statement after an earlier change to the s…
claude Oct 22, 2026
34cbdd9
docs(proposal): the complete chess report corrects this document's ow…
claude Oct 22, 2026
1b1c23b
fix: alter settings configuration accepts ExtraJvmParameters
claude Oct 22, 2026
d3e8fb8
fix(alter page): a widget-name miss names the object-list item addresses
claude Oct 22, 2026
ac715c6
docs(wiki): mutator-addressing digests the click-action keys and the …
claude Oct 22, 2026
33d1879
fix: splice a reworded, added or removed free note (mendixlabs/mxcli#…
claude Oct 22, 2026
47920d8
docs(changelog): microflow-splice fixes for mendixlabs/mxcli#1489, #1…
claude Oct 22, 2026
b7f4028
feat(grammar): address a legacy table cell by position, `table1 cell(…
claude Oct 22, 2026
eef55bd
fix: refuse [id = $obj/System.owner] when the entity stores no owner
claude Oct 22, 2026
62fe0f1
fix: refuse create/change of System.owner with advice that applies
claude Oct 22, 2026
69cb58c
test: exec an association to a System entity end to end (ako/mxcli#1255)
claude Oct 22, 2026
017bbfd
Merge remote-tracking branch 'origin/main' into claude/bold-pascal-tu…
claude Oct 22, 2026
e17e77b
feat(alter page): fill, replace and empty a legacy table cell by posi…
claude Oct 22, 2026
50ad810
docs: mxcli syntax shows the ExtraJvmParameters configuration key
claude Oct 22, 2026
5957af5
fix: marketplace install/update writes package metadata into the app …
claude Oct 22, 2026
74e344c
feat(describe): list a legacy table's cell addresses and contents
claude Oct 22, 2026
ee7169b
fix: marketplace diff/update fail with 'path too long' under %TEMP%
claude Oct 22, 2026
7b8a4de
test: name the new bug-tests by their upstream issue numbers
claude Oct 22, 2026
712ba4e
fix: alter settings webui sets OptimizedClient, and describe emits it
claude Oct 22, 2026
66a6001
fix(alter page): a column SET keeps the dynamicText template it hides…
ako Oct 22, 2026
8378798
docs: legacy table cell addresses in ALTER PAGE reference, skill and …
claude Oct 22, 2026
fad28b6
fix: describe no longer prints a view entity's association as a state…
claude Oct 22, 2026
ace4d5d
fix: describe → exec no longer re-indents a view entity's stored OQL
claude Oct 22, 2026
bc75ffc
fix: replaying an XML-schema mapping's description no longer drops it…
claude Oct 22, 2026
1dd7855
docs(wiki): describe-round-trip-gaps — replaying a description as a n…
claude Oct 22, 2026
a609edb
fix: check refuses an unknown alter settings section or key, as exec …
claude Oct 22, 2026
4145222
Merge pull request #1619 from ako/claude/youthful-planck-x6x8xk
ako Oct 23, 2026
a11a26e
Merge pull request #1621 from ako/feat/1453-table-cell-address
ako Oct 23, 2026
2c2cceb
Merge remote-tracking branch 'origin/main' into claude/bold-pascal-tu…
claude Oct 23, 2026
9404715
docs: docker check does not download MxBuild or use Docker
claude Oct 23, 2026
0fa7c77
docs(wiki): re-sync package-operations-damage from the marketplace fi…
claude Oct 23, 2026
d710952
Merge branch 'mendixlabs:main' into main
ako Oct 23, 2026
77ff9bb
test(roundtrip): strike the TestApp entries the describe fixes repaired
claude Oct 23, 2026
b264f14
Merge remote-tracking branch 'origin/main' into claude/mutator-addres…
claude Oct 23, 2026
2f27839
Merge pull request #1624 from ako/claude/system-module-references-iss…
ako Oct 23, 2026
08bec0d
test: a reworded free note is written, not refused; gofmt splice_hand…
claude Oct 23, 2026
33ad8ba
fix: find/filter by System.owner builds, and describe keeps System as…
claude Oct 23, 2026
f873689
Merge origin/main into claude/awesome-fermi-2vhkj6
claude Oct 23, 2026
d6d8422
Merge remote-tracking branch 'origin/main' into claude/bold-pascal-tu…
claude Oct 23, 2026
c99e3e1
Merge pull request #1627 from ako/claude/settings-configuration-issue…
ako Oct 23, 2026
0c812d7
fix: create configuration on 11.12+ mints fresh ids for the copied Op…
claude Oct 23, 2026
a4f9ecb
feat: alter settings configuration sets MaxJavaHeapSize
claude Oct 23, 2026
ca32d59
fix: run --local passes the configuration's JVM options to the runtime
claude Oct 23, 2026
3cef0f9
docs: describe settings takes no category, only CONFIGURATION 'name'
claude Oct 23, 2026
7c7668e
Merge pull request #1626 from ako/claude/describe-round-trip-gaps-ibgvit
ako Oct 23, 2026
ff69c3a
fix: read a SOAP mapping's imported web service under its storage key
claude Oct 23, 2026
3074c5f
fix: keep a view query's outer comments, and gate OQL comments on 11.7
claude Oct 23, 2026
97d15f3
Merge pull request #1630 from ako/claude/cli-contract-defects-nm60k1
ako Oct 23, 2026
6b31dde
Merge pull request #1625 from ako/claude/mutator-addressing-issues-pv…
ako Oct 23, 2026
127beb6
Merge pull request #1623 from ako/claude/awesome-fermi-2vhkj6
ako Oct 23, 2026
03f46e6
Merge remote-tracking branch 'origin/main' into claude/system-module-…
claude Oct 23, 2026
d6f7246
Merge remote-tracking branch 'origin/main' into claude/bold-pascal-tu…
claude Oct 23, 2026
0466a33
Merge pull request #1634 from ako/claude/settings-configuration-issue…
ako Oct 23, 2026
a059cb3
Merge pull request #1635 from ako/claude/describe-round-trip-gaps-ibgvit
ako Oct 23, 2026
c289c6e
Merge pull request #1633 from ako/claude/system-module-references-iss…
ako Oct 23, 2026
2254ae5
Stop mirror.py from duplicating mirrors on a short listing
claude Oct 23, 2026
2c8d621
Merge remote-tracking branch 'origin/main' into claude/bold-pascal-tu…
claude Oct 23, 2026
7adbfbf
Merge pull request #1628 from ako/claude/bold-pascal-tuwjn8
ako Oct 23, 2026
8a762d8
Merge pull request #1638 from ako/claude/funny-lovelace-wtudp7
ako Oct 23, 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
11 changes: 4 additions & 7 deletions .claude/commands/mendix/validate-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This is the same validation that Studio Pro performs - it checks for consistency

## Prerequisites

The `mx` command must be available. In a dev container, run `mxcli setup mxbuild -p app.mpr` to auto-download it.
The `mx` command must be available; `mxcli docker check` does not download it. In a dev container, run `mxcli setup mxbuild -p app.mpr` once to download it.

**Where to find `mx`:**

Expand All @@ -23,14 +23,11 @@ The `mx` command must be available. In a dev container, run `mxcli setup mxbuild
## Command

```bash
# In dev container (after mxcli setup mxbuild -p app.mpr)
# After mxcli setup mxbuild -p app.mpr (docker check does not download mxbuild)
mxcli docker check -p app.mpr

# Or use the integrated command (auto-downloads mxbuild)
mxcli docker check -p app.mpr

# With explicit path
/path/to/mxbuild/modeler/mx check /path/to/project.mpr
# With an explicit MxBuild (still checks a temporary copy; bare `mx check` writes into the project)
mxcli docker check -p app.mpr --mxbuild-path /path/to/mxbuild
```

## Example Output
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-22", "symptom": "`mxcli docker --help` lists \"Mendix 11.6.1 or later\" as a requirement, yet `docker check` works on a Mendix 10.24 app; with an mxbuild of the project's minor but another patch, `update-widgets` fails with exit 4 and the check carries on — then ends with \"Note: widget definitions were normalised on a temporary copy\" a few lines after \"Warning: update-widgets failed (continuing): exit status 4\"", "cause": "The 11.6.1 floor is `docker build`'s (`build.go`, Portable App Distribution) but sat in the command group's Requirements, so it read as every subcommand's; `check` has no gate. `mx update-widgets` refuses a project whose version is not exactly mx's own (\"Project is in different Mendix version - <v>\", exit 4) while `mx check` accepts it, and `Check` printed its normalisation note whenever update-widgets was *requested*, not when it succeeded", "file": "`cmd/mxcli/docker.go` (`dockerCmd.Long`, `dockerCheckCmd.Long`), `cmd/mxcli/docker/check.go` (`Check`)", "insight": "Exit 4 is a version mismatch, not Mendix 10: measured by relabelling a real 10.24.18 v1 project's `_MetaData._ProductVersion` to 10.24.13 — mx 10.24.18's update-widgets exits 4 with that message, its mx check reports 0 errors, and an unrelabelled project exits 0 on both (v2 and v1). `mx update-widgets --help` documents only \"0 if Ok\", so the message is the only diagnosis; `--loose-version-check` would upgrade the copy instead, which changes what is checked. A mismatched mx is reached easily because `ResolveMxForVersion` falls back to PATH and any cached version. A version floor in a command *group*'s help is read as every subcommand's: put it on the subcommand that enforces it, and pin the help to the enforcing line with a test. A closing note that describes a step must key on that step's outcome, not on whether it was requested", "test": "`cmd/mxcli/docker_help_test.go` (`TestDockerHelp_VersionFloorIsBuildsNotChecks`), `cmd/mxcli/docker/check_readonly_test.go` (`TestCheck_FailedUpdateWidgetsIsNotReportedAsNormalised`)", "refs": ["mendixlabs/mxcli#1629", "#1561"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-22", "symptom": "`mxcli git note -p App.mpr --write | head -1` writes no mx_metadata note and says nothing: the pipeline exits with head's status 0 (141 under pipefail), `git notes --ref=mx_metadata show HEAD` reports no note; `| tail -1` and an unpiped run both write it", "cause": "`annotateCommits` printed each commit's note (one JSON line, ~660 KB on a whole-project commit) before writing it. A Go program writing to a stdout whose reader has gone is killed by SIGPIPE, so the first print to the closed pipe ended the process ahead of `writeNote` — for that commit and every later one", "file": "`cmd/mxcli/cmd_git.go` (`annotateCommits`)", "insight": "Any print that precedes a side effect is a kill point once stdout is a pipe: Go dies on EPIPE to fd 1 unless SIGPIPE is notified or ignored, so ignoring Fprintf's error changes nothing. Do every write first and report afterwards; a preview with no side effect can stream. The issue's own suggestion (write then print, per commit) is not enough with two commits — the second print still kills before the second write, and a two-arm control showed exactly that (HEAD~1 written, HEAD lost). That same arm explains the upstream \"verified fixed on main\" comment: it reported exit 141 on both builds and 1 note for a repository two commits ahead, which is the race landing differently, not a fix — `annotateCommits` was unchanged on that commit. Test with a pipe whose read end is closed before the child starts: `| head -1` with the race taken out, so a small fixture note is enough; assert the child ended on SIGPIPE as the control that the scenario fired", "test": "`cmd/mxcli/gitnote_sigpipe_test.go` (`TestGitNote_WriteSurvivesAClosedStdout`, real main() in a child via TestRunMainHelper)", "refs": ["mendixlabs/mxcli#1490", "#1346"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli/marketplace", "date": "2026-10-22", "symptom": "`mxcli marketplace update <id> -p app.mpr --to <version>` (and `marketplace install`) leaves the package's own metadata in the app root: `manifest.json`, `License.txt`, `SiemensMendix<Module>__<ver>__READMEOSS_<timestamp>.html` (and on BusinessEvents, `Mendix EULA.docx`) show up as untracked files. Model and mx check are fine.", "cause": "InstallPackageFiles copied every archive entry except project.mpr and package.xml. package.xml's `<modelerProject><files>` list is the package's declaration of its project files, and nothing read it; the publisher's metadata sits at the archive root, undeclared.", "file": "`cmd/mxcli/marketplace/update.go` (`declaredProjectFiles`, `isProjectFile`, `ReasonNotAProjectFile`), `cmd/mxcli/cmd_marketplace_update.go` (`reportSkippedFiles` groups them on one line); tests `cmd/mxcli/marketplace/install_declared_files_test.go`, `cmd/mxcli/cmd_marketplace_skipped_report_test.go`", "insight": "The arbiter was one `mx module-import` into a blank 11.12.1 app with a before/after `find`: mx wrote exactly the `<files>` entries of ExternalDatabaseConnector 6.3.0 + BusinessEvents 3.12.1 (175 + 16), no root file, and silently passed over a listed entry the archive lacks (the snowflake jar stripped from mx-modules/). That settles both 'which entries' and 'is a missing listed entry an error' without guessing. Comparing `<files>` against `unzip -Z1` on every .mpk in the repo first showed the only undeclared entries are root-level metadata — cheap, and it is what made the declared list safe to trust. The earlier relative-path test (finding 2026-09-20) used manifest.json as its 'legitimate entry' and so encoded this bug as expected behaviour; check old tests' fixtures when tightening what gets installed. Distinguish an empty `<files/>` (installs nothing) from no list (fallback: skip root-level entries only).", "refs": ["mendixlabs/mxcli#1487", "ako/mxcli#1344"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli/marketplace", "date": "2026-10-22", "symptom": "On Windows, `mxcli marketplace diff` / `update` fail building the reference project: `Extracting module files into C:\\Users\\<user>\\AppData\\Local\\Temp\\mxdiff1185592798\\target-ref` then `The specified file name or path is too long, or a component of the specified path is too long.` Works with `TMP=C:\\mxt`.", "cause": "mx refuses any file path of 260+ characters ITSELF (Mendix FileSystem.OpenNewFileForWriting throws PathTooLongException), on every OS. The reference project was built in os.MkdirTemp(\"\", \"mxdiff\")/target-ref — %TEMP% is ~28+len(user) on Windows — and bundled node_modules reach 181 (11.12.1 blank template) to ~202 (NanoflowCommons 7.x) characters, so 7.x fit for no user name.", "file": "`cmd/mxcli/marketplace/workdir.go` (`NewWorkDir`, `workRoot`, `mxFailure`, `mxMaxPath`), callers in `cmd/mxcli/cmd_marketplace_{diff,update,install}.go` (one-letter slot dirs), `scratch.go` (hint on mx failure); tests `workdir_test.go`, `workdir_integration_test.go` (-tags integration, real mx)", "insight": "The 'Windows-only' bug reproduces on Linux: the first `mx create-project` in the scratchpad (~85-char path) threw PathTooLongException, which is what exposed that the limit is mx's, not the OS's — then a bisection on base-dir length (77 ok / 78 fails for create-project; 259 ok / 260 fails for module-import of a 200-char entry) pinned it exactly, with the reported message verbatim. So no Windows box is needed: point TMPDIR at a 48-char dir and import a package with one deep declared entry. Sizing came from the deepest file in a real blank app plus the npm tarballs NanoflowCommons 7.x pins (registry.npmjs.org is reachable; marketplace downloads need a PAT). Wrong turns to skip: a relative .mpr or --output-dir does not help (mx resolves to absolute, and create-project --output-dir ./x throws UriFormatException); and a drive-root default like C:\\mxt is NOT safe — children of C:\\ inherit Authenticated Users:Modify, so another account could swap the package before import. Shortest PRIVATE root wins (%USERPROFILE%\\.mxcli\\t, /tmp via 0700 MkdirTemp, or TMP/TMPDIR if shorter); that still bounds the Windows user name at ~22 chars for 202-char packages, hence the hint naming dir, length and remaining budget.", "refs": ["mendixlabs/mxcli#1486", "ako/mxcli#1343"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-23", "symptom": "On a fresh machine `mxcli docker check -p app.mpr` fails with \"mx not found; specify --mxbuild-path pointing to Mendix installation directory\", although the tutorial says \"The first time you run this, it will download the MxBuild toolchain\", docker.md and CLAUDE.md say \"auto-downloads mxbuild\", and the README calls it \"the integrated command\"; the tutorial also says it runs mx check \"inside a Docker container\"", "cause": "`Check` resolves mx with `ResolveMxForVersion` (--mxbuild-path, PATH, Studio Pro, OS locations, exact cache, any cache) and has never downloaded — git history shows `DownloadMxBuild` only in `ResolveMxForNewProject` (`mxcli new`) and `Build`. It runs mx with exec.Command, never a container. The docs generalised `docker build`'s download and the `docker` command group's name onto check", "file": "`cmd/mxcli/docker/check.go` (`Check`), `cmd/mxcli/docker.go`, docs-site `tools/docker-check.md`, `tools/docker.md`, `tutorial/validation.md`, `README.md`, `CLAUDE.md`, `.claude/commands/mendix/validate-project.md`", "insight": "Settle \"does it download / does it use Docker\" by running it, not by reading the call: an empty HOME (fails, downloads nothing) and docker/podman replaced by stubs that log and fail (passes, 0 calls) — the second matters because Docker was installed, so a passing run proved nothing. Before rewording a doc that promises behaviour, check git history for whether the code once had it (`git log -S DownloadMxBuild -- check.go`): a lost feature is fixed in code, a never-true doc in the doc. Grep beyond the reported file — the claim was in seven places, two of them synced into user projects where agents read them. The error a doc-follower lands on is part of the doc: it now names `mxcli setup mxbuild`. The test holds each section that mentions docker check and downloading to say \"does not download\", with fenced `#` comments not treated as headings; the shared `ResolveMxForVersion` error was left alone because eight callers use it", "test": "`cmd/mxcli/docker_check_docs_test.go` (`TestDockerCheckDocs_SayItDoesNotDownload`), `cmd/mxcli/docker/check_readonly_test.go` (`TestCheck_MissingMxNamesSetupNotADownload`)", "refs": ["#1561", "mendixlabs/mxcli#1629"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-23", "symptom": "A configuration's Extra JVM parameters (e.g. `-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=29758`, the proxy mendixlabs/mxcli#131 was filed for) and its Java heap maximum were set in the model and shown by `describe settings`, yet absent from every `mxcli run --local` / `test --local` app — silently", "cause": "LocalRuntimeOptions.jvmArgs was a fixed list (mxcli's two -D flags, then -jar). Nothing read ServerConfiguration.ExtraJvmParameters or MaxJavaHeapSize on the run path, although the configuration was already resolved there for its constant values", "file": "cmd/mxcli/runjvm.go (configurationJVMArgs, splitJVMParameters, reportJVMArgs); cmd/mxcli/runconstants.go (chooseConfiguration, extracted); cmd/mxcli/constants_resolve.go (constantChain.JVMArgs); cmd/mxcli/docker/localboot.go (LocalRuntimeOptions.JVMArgs, jvmArgs), localapp.go, runlocal.go; cmd/mxcli/testrunner (RunOptions.JVMArgs); cmd_run.go, cmd_test_run.go", "insight": "Same shape as the constants of FINDINGS §33: a configuration value reaches Studio Pro's run and not mxcli's, and nothing errors. Resolve it from the SAME configuration choice and the same project read as the constants (chooseConfiguration, carried on constantChain) — a second resolver would drift, a second read would open the project twice. Verify on the process, not the options struct: booted the blank 11.14.0 app with MaxJavaHeapSize 768 and `-Dmxcli.probe=\"from the configuration\" -Dhttps.proxyPort=29758`; /proc/<pid>/cmdline of the runtime JVM held -Xmx768m, `-Dmxcli.probe=from the configuration` (one argument, quotes resolved) and the port, all before -jar; the main build's JVM held none of them. Order is load-bearing: after -jar they are the runtime's arguments, not the JVM's; after mxcli's own -D flags so a deliberate property wins; heap before parameters so an explicit -Xmx wins. The report omits -D values (a trust-store password goes there too; run output reaches CI logs). An unbalanced quote is refused before boot rather than passed on split wrongly. `mxcli docker run` is a separate path and not covered", "refs": ["mendixlabs/mxcli#131", "ako/mxcli#1225"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/backend/pagemutator", "date": "2026-10-22", "symptom": "`set (ShowContentAs: attribute) on dg column(Name)` on a column created as dynamicText: the project as stored fails with CE0463 at the Data grid 2 (0 errors before the SET, and for a column created as attribute)", "cause": "ResetHiddenColumnProperties reset hidden PRIMITIVE column properties only (#1519); the column's dynamicText TextTemplate, hidden unless showContentAs is \"dynamicText\", stayed filled where CREATE stores null", "file": "`mdl/backend/pagemutator/column_hidden_reset.go` (column path now passes the template constructor), `mutator.go` (`SetColumnProperty` creates a null template before writing its text)", "insight": "Same defect as the Accordion group's headerText, found by measuring rather than by analogy: the column-vs-control diff (TypePointer -> PropertyKey in the JSON dump) showed only dynamicText differing ('Item {1}', one param vs null). Only `docker check --no-update-widgets` shows it. The reverse switch is refused unless the text is given, because the schema DefaultValue is \"\". Side quirk left as is: in a column SET `Content:` resolves to the custom-content SLOT (schema key `content`, case-insensitive) before the `dynamicText` alias CREATE uses, so describe prints `Content: 'Item'` that a SET cannot write back — use `dynamicText:`; and `ContentParams` does not parse in a SET at all", "refs": [], "ce": ["CE0463"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/backend","date":"2026-10-22","symptom":"mendixlabs/mxcli#1489 (ako/mxcli#1345): under `mdl 1;` an activity with `on error [without rollback] begin … end error` could not be changed in place. `create or modify` with one call argument changed (or only the handler's log text) was refused and advised `alter`; the advised `alter … replace` was refused with 'cannot replace the ActionActivity at (360, 200): it has an error handler, which would be left with no activity; rewrite the flow with create or modify instead'","cause":"mfmutator removable() refused any drop or replace of an activity with an outgoing error flow, whatever the replacement; create or modify reached the same refusal because patchDiff treated the handler body as part of the activity (a change inside the handler became a replace of the call), and lcsStatements did not pair such an activity, so a neighbouring change merged with it","file":"mdl/backend/mfmutator/splice.go (replaceKeepingHandler, swapInPlace, serializeInPlace, removable), mdl/executor/flow_splice_error_handler.go (sameHandlerShell, handlerEdit, keepStoredHandler, storedStatementAt), mdl/executor/cmd_flow_modify.go (gap, lcsStatements), mdl/executor/cmd_alter_flow.go (applyTo), mdl/ast/ast_alter_flow.go (KeepHandler)","fix":"Replace of a top-level activity with a custom handler by ONE activity whose action has the same ErrorHandlingType is an in-place swap (shared with replaceInLoop): same collection slot, stored position and size, every flow in/out — the error flow included — repointed; the handler's activities and rejoin merge untouched. create or modify pairs same-kind activities with the same handler kind, replaces the activity with KeepHandler when it changed, and diffs the handler body like an if branch. alter recognises a restated handler by comparing with the stored statement from the full-layout describe (sameIgnoringLayout) and strips the fragment to its entry activity; another handler is refused with advice to address the handler's activities by handle. Remaining refusals name drop-and-create, never create or modify","test":"mfmutator splice_handler_test.go TestSplice_ReplaceKeepsTheErrorHandler (byte-exact expected unit), TestSplice_ReplaceOfAHandledActivityRefusals; executor flow_splice_error_handler_pedapp_test.go TestCreateOrModify_ActivityWithErrorHandlerIsSplicedInPlace (T1, T3, both, T4 returning handler; ids/positions kept, re-run Unchanged, control: handler kind change refused), TestAlter_ReplaceOfActivityWithErrorHandler (T2; refusals not circular). Source reverted: every subtest fails with 'rewrite the flow with create or modify instead'","insight":"Two refusals that each advise the other mode are a sign the shared primitive refuses too broadly: the mutator refused on the presence of an error flow instead of asking whether the replacement keeps it valid (one activity, same custom ErrorHandlingType). The handler body is just more top-level nodes — diffing it like an if branch was enough for T3. The fake serializer in splice_test.go had no Action/ErrorHandlingType, so it had to grow one before the mutator test could express the case","refs":["mendixlabs/mxcli#1489","ako/mxcli#1345","mendixlabs/mxcli#1517","ako/mxcli#1399"]}
Loading
Loading