Skip to content

mxcli v0.27 exec is all or nothing; STOP #22, learned-detection-gaps, iterative-build-loop and exec.sh still say it is "not transactional", and the "non-idempotent statement last" pattern no longer works #539

Closed

Description

@AlvinnYeo

Files at 393d253: skills/learned-mdl-preflight.md line 59 (STOP #22); skills/learned-detection-gaps.md line 31; skills/iterative-build-loop.md line 287; project-bin/exec.sh lines 1615 and 1739-1741 ("PARTIAL APPLICATION LIKELY") · mxcli: v0.27.0 · Mendix: 11.14.0

Summary

The mxcli v0.27.0 release notes: "exec is all or nothing: when a statement fails at write time, the whole run is
rolled back, so a script never leaves a project half-changed" (mendixlabs/mxcli#1408). Reproduced:

-- r2.mdl (second run; the first run created both entities)
create or modify persistent entity M.E (A: String(50), C: Integer);   -- edited: adds C
create persistent entity M.F (B: String(10));                         -- bare create, already exists

$ mxcli exec r2.mdl -p <app>.mpr
Modified entity: M.E
Error: entity already exists: M.F — ...
Nothing was written: statement 1 was rolled back, and the project is as it was before exec
exit 1
$ mxcli -c 'describe entity M.E'   ->  A only; C is not there

The toolkit still teaches the old behaviour:

Place Text today True on v0.27?
learned-mdl-preflight.md STOP #22 "mxcli is not transactional across statements ... the earlier statements stay written" No
learned-detection-gaps.md:31 "the failing statement stops the script and every statement below it is silently skipped" Half. Nothing below runs, but nothing above is kept either
iterative-build-loop.md:287 "partial changes are already live" No
exec.sh:1739-1741 "PARTIAL APPLICATION LIKELY ... everything before the failing statement is already in the model" No. It misleads the reader of a failed run

A pattern this breaks. Projects that followed the old rule put the one statement with no idempotent form (an
alter page ... insert, a drop enumeration without if exists, a bare create) last. A re-run then "re-applies
everything above it, then is refused" and the model still gets the earlier edits. On v0.27, the refusal of that last
statement rolls back the whole run. Any edit made to an earlier statement is silently not applied, and the exit code
is 1 on every re-run. The "exec twice, the second run writes nothing" check becomes a failure instead of a no-op.

STOP #22's conclusion is still right: one owner per document, create or modify / if not exists everywhere,
and a from-empty replay. Only the reasoning and the consequences changed.

Suggested fix (ranked)

  1. Rewrite the four passages, version-gated: "Before v0.27.0, exec was not transactional (earlier statements stayed
    written). From v0.27.0 it rolls back the whole run on any write-time failure ('Nothing was written: statement N was
    rolled back')." Keep STOP Docs: "Where you run this" visual (guide §5, README, SVG) and the Docker-on-WSL2 / lanes-mix notes #22's rule. Add the new consequence: a non-idempotent statement anywhere, first or last,
    makes the whole script fail on re-run and drops every edit in it.
  2. Add a STOP row (or extend Docs: "Where you run this" visual (guide §5, README, SVG) and the Docker-on-WSL2 / lanes-mix notes #22): "never rely on placing a non-repeatable statement last". Give one-shot statements
    their own script, or comment them out after the first exec with a dated note.
  3. exec.sh: on a failed exec, read mxcli's version (or grep the output for Nothing was written) and print
    "rolled back by mxcli, nothing applied" instead of "PARTIAL APPLICATION LIKELY". Keep the gate run either way.
  4. The STOP-table pre-exec scan (Turn the learned-mdl-preflight STOP table into a static pre-exec scan #349) could warn on a script whose last statement has no idempotent form.

How to retest

The two-statement script above on a scratch app, run twice: on v0.27+ the second run exits 1 with "Nothing was
written", and the first entity keeps its old definition.

Activity

  1. MendixMau commented on Oct 26, 2026

    @MendixMau
    Owner

    Fixed in #578 (squash a088b4e). STOP #22, learned-detection-gaps, iterative-build-loop and exec.sh now say v0.27+ exec is all-or-nothing. exec's message is conditional on mxcli printing "Nothing was written", since a failed rollback can leave the project partly updated (checked against cmd_exec.go).


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions