fix(new): resolve the exact Mendix version, and verify what was created - #69
Merged
Conversation
`mxcli new --version 11.12.2` printed "Step 1/4: Resolving MxBuild 11.12.2..."
and then produced a Mendix 11.6.6 project, with no warning that the requested
version had been ignored. `mxcli setup mxbuild --version 11.12.2` downloads that
version fine, so the CDN was never the problem — the resolver simply never asked.
ResolveMxForNewProject delegated to ResolveMxForVersion, whose last resort is
AnyCachedMxPath(): any cached mx, of any version. That fallback is defensible
when the project already exists and its version is a preference. It is wrong for
`new`, where the requested version is not a preference but the definition of the
output — `mx create-project` stamps the new project with the version of the
binary that ran it, and every later step (init, mxbuild, runtime, run --local)
then follows the wrong version.
Two changes, because either alone leaves a silent path.
Resolution is now exact. localMxForVersion looks only for the requested version:
an exact-version Studio Pro install, an exact-version binary in the OS-specific
install locations, then the exact-version download cache. PATH is deliberately
excluded — an `mx` on PATH carries no version guarantee. Anything else
downloads. Windows and macOS still prefer an exact Studio Pro install, so they
do not fetch a Linux CDN binary that cannot execute.
And `new` now checks its postcondition rather than trusting the resolution: it
reopens the created .mpr, compares ProductVersion against --version, and exits
with the mismatch, the binary that caused it, and the setup command that fixes
it. A resolution bug is invisible without this — which is exactly how the
original went unnoticed.
Verified by reproducing the reported state (only 11.6.6 cached, 11.12.2
requested):
before -> silently created a Mendix 11.6.6 project
after -> downloads 11.12.2, creates a Mendix 11.12.2 project
and by reverting only the resolver, which now fails loudly instead of silently:
Error: requested Mendix 11.12.2 but the created project is 11.6.6.
mx create-project stamps the project with the version of the binary that ran it (.../11.6.6/modeler/mx).
Run 'mxcli setup mxbuild --version 11.12.2' and try again.
Unit tests cover the resolution decision without touching the network: a cached
11.6.6 must not satisfy a request for 11.12.2, an exact match must still be
reused rather than re-downloaded, and an empty version matches nothing.
Found while building a project to verify mendixlabs#812 in a browser; it cost a full
project rebuild before the wrong version was spotted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
Same recurring conflict as #68: .claude/skills/fix-issue.md, where every fix appends a symptom row at the identical anchor. Both sides kept. check.go auto-merged cleanly — #64's runUpdateWidgets and this branch's localMxForVersion touch different functions. Parser regenerated against #66's grammar; full suite green.
ako
pushed a commit
that referenced
this pull request
Aug 1, 2026
Every bug fix touches .claude/skills/fix-issue.md, and new rows went in directly under the table header. Two branches fixing unrelated bugs therefore inserted at the same line, which git cannot merge — a conflict by construction rather than by bad luck. It cost five separate resolution rounds in one week (#59-#62 three times, then #68 and #69), and each round risks silently dropping a row: one earlier round was "resolved" by deleting a PR's rows entirely and restoring them in a follow-up. Appending puts each branch's insert at a different offset, which git merges without help. The table is unordered — it is looked up by matching a symptom, not read top to bottom — so position carries no meaning and appending costs nothing. Recorded in both places a contributor might look: the skill's How to Use, with the reasoning so it is not "fixed" back, and the PR checklist item in CLAUDE.md. Existing rows are deliberately left where they are. Reordering them would conflict with every open branch at once, which is the problem this change exists to avoid. Folded into this branch rather than opened separately: it edits the same How to Use block, so a sixth branch would have manufactured exactly the conflict it is meant to prevent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
#68 landed, putting its symptom row at the top of the table — the same line this branch inserts at, so the conflict recurred immediately after the previous resolution. That is the pattern, not bad luck. Resolved by keeping main's rows and moving this branch's row to the END of the table, which is the convention #70 introduces. Applying it here rather than waiting: this branch is the exact case it exists for.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
mxcli new --version 11.12.2printed:…and then produced a Mendix 11.6.6 project, with no warning that the requested version had been ignored.
mxcli setup mxbuild --version 11.12.2downloads that version fine, so the CDN was never the problem — the resolver simply never asked.ResolveMxForNewProjectdelegated toResolveMxForVersion, whose last resort isAnyCachedMxPath(): any cached mx, of any version. That fallback is defensible when the project already exists and its version is a preference. It is wrong fornew, where the requested version is not a preference but the definition of the output —mx create-projectstamps the new project with the version of the binary that ran it, and every later step (init, mxbuild, runtime,run --local) then follows the wrong version.Two changes, because either alone leaves a silent path
Resolution is now exact.
localMxForVersionlooks only for the requested version: an exact-version Studio Pro install, an exact-version binary in the OS-specific install locations, then the exact-version download cache. PATH is deliberately excluded — anmxon PATH carries no version guarantee. Anything else downloads. Windows and macOS still prefer an exact Studio Pro install, so they do not fetch a Linux CDN binary that cannot execute.newnow checks its postcondition rather than trusting the resolution: it reopens the created.mpr, comparesProductVersionagainst--version, and exits with the mismatch, the binary that caused it, and the command that fixes it. A resolution bug is invisible without this — which is exactly how the original went unnoticed.Verification
Reproducing the reported state (only 11.6.6 cached, 11.12.2 requested):
And reverting only the resolver, to prove the postcondition is not decorative:
Unit tests cover the resolution decision without touching the network: a cached 11.6.6 must not satisfy a request for 11.12.2, an exact match must still be reused rather than re-downloaded, and an empty version matches nothing. Full suite green.
How it was found
While building a scratch project to verify mendixlabs#812 in a browser. It cost a full project rebuild before the wrong version was spotted — the created project simply reported
Mendix 11.6.6in a later command's banner, which is the only place the substitution ever surfaced.The generalisable lesson is recorded in the symptom table: when a flag names the version or identity of the artifact being produced, a "close enough" local substitute is never valid, and the produced artifact should be verified against the request rather than the resolution trusted.
🤖 Generated with Claude Code
https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
Generated by Claude Code