Skip to content

fix(exec): roll back the model write when mxbuild crashes - #424

Merged
MendixMau merged 2 commits into
masterfrom
fix/exec-crash-rollback
Oct 16, 2026
Merged

MendixMau merged 2 commits into
masterfrom
fix/exec-crash-rollback

Conversation

@MendixMau

Copy link
Copy Markdown
Owner

What changed and why. On the default path, when mxbuild exits non-zero without an error list after the write, exec.sh kept the write ("Snapshot preserved"). The next exec then reports "Baseline NOT measured" and builds on a model nothing could load (field incident 2026-10-13, #309). This extracts only the crash-rollback hunk from #311 (about 23 lines): when a baseline was measured (BASE_KNOWN=1) the crash is a property of the write, so the snapshot is restored and one BUILD-LOG row says so. No guard, no new refusal. Without a measured baseline and in --patch mode nothing changes.

Impact

Row Answer
Process No new human step, gate or refusal. A crash after a measured baseline now rolls the write back (same restore as a failed gate); the script is re-run after fixing it.
Dependencies project-bin/exec.sh (one hunk in the MXBUILD_EXIT -ne 0 branch; uses BASE_KNOWN, PATCH_MODE, restore_snapshot, RESTORED, all on master). #384 (--on-copy) rebases over one small hunk. No new artifact read.
Context cost none: no routed or always-loaded file touched
Behaviour n/a: scripts only
Runtime n/a: only the crash path runs extra code (one snapshot restore).

Field evidence. Synthetic only: stub mxcli, mxbuild and java in a throwaway git repo. The original incident is the 2026-10-13 two-hop data source crash (Mendix 11.14.0, mxcli v0.25.0).

Tests. New tests/wave2/test-exec-crash-rollback.sh: A normal success unchanged; B baseline ok then crash exit 137 leaves the model byte-identical, one row; C crash on the baseline too keeps the old behaviour; D clean error list takes the ordinary gate-failed path.

  • this branch: PASS 13 / FAIL 0

  • master exec.sh as subject: PASS 9 / FAIL 4 (all in B)

  • also run, no regression: test-exec-lock-watch 84/0, test-exec-change-class 21/0. test-exec-hash-verify has 1 known macOS failure (case K, fixed in the sibling test PR). test-exec-approval gives 13/30 on both master and this branch (unchanged).

  • No client data anywhere in the diff

  • Size cap: 2 code files, about 24 lines of script plus the test

  • Test tier: T1 synthetic

  • CHANGELOG line added

🤖 Generated with Claude Code

When mxbuild exits non-zero without an error list after a measured baseline, restore the
snapshot instead of keeping the write. Without a baseline and in --patch mode behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MendixMau
MendixMau merged commit 65a160e into master Oct 16, 2026
2 checks passed
MendixMau added a commit that referenced this pull request Oct 16, 2026
Independent review: APPROVE.

# Review: PR #425, single-slash TMPDIR in test-exec-hash-verify case K

- Head: `8175defd` (`test/hash-verify-single-slash`), 2 commits on master `2def0679`. `tests/wave2/test-exec-hash-verify.sh` (+3/-1) and one CHANGELOG line. No script change.
- Read-only detached worktree under /tmp, removed afterwards. macOS 26.6, `TMPDIR=/var/folders/.../T/` (trailing slash).

## Checked

| Run | Result |
|---|---|
| master test, default TMPDIR | 42 passed, 1 failed: `K: MXPATCH_BACKUP_DIR=/var/folders/.../T/exec-hv.X/proj/...` (exec.sh reports a single slash, the test's `$P` holds `T//`) |
| branch test, default TMPDIR | **43 / 0**, the claim reproduced |
| branch test, `TMPDIR=/tmp` | 43 / 0 (`/tmp` symlink to `/private/tmp`: `pwd -P` and exec.sh's own `cd` agree) |

Cause and fix are right. `cd "$(mktemp -d …)" && pwd -P` drops the `//` and resolves the symlink. exec.sh then runs inside that physical path, so the path it hands over has the same form. The fix is the same pattern #424's new test and T3 recommend for #384's test. On Linux nothing changes.

## Items

1. Add `|| exit 2` to the new `WORK=` line, like `test-exec-approval.sh` and #424's test do. If `mktemp` or `cd` fails, `WORK` is empty and `P="/proj"`. The fixture then tries to create directories at `/`. The `mkdir` there fails rather than doing damage, but the run reports a pile of FAILs instead of one clear exit 2.
2. Optional: the header's positive-control counts (lines 14-21) are still correct. The CHANGELOG line is accurate.

## Verdict

**APPROVE**: item 1 is a one-token hardening. Fold it in or take it as a follow-up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant