Skip to content

mxcli docker check silently converts MPRv2 projects to MPRv1 (via mx update-widgets), deleting mprcontents #763

Description

@dimenus

Summary

mxcli docker check silently converts an MPRv2 project to the self-contained MPRv1 storage
format. It inlines every unit into the .mpr (adds the Unit.Contents column) and deletes
the entire mprcontents/ directory. A command whose job is to check the project should not
rewrite the on-disk storage format.

The cause is the mx update-widgets step that mxcli docker check runs before mx check.
update-widgets performs the conversion; the check itself does not.

On a project under Git this is damaging: after the conversion the working tree no longer
matches the mprcontents/*.mxunit files tracked in the repository. If the project is then
opened in Studio Pro (which auto-converts back to MPRv2) or the state is committed, the
history and the on-disk format drift apart. In our case Studio Pro 11.12.1 then failed to
open the project at all, crashing in its Git version-control provider
(LibGit2RepositoryProvider.WriteBaseFile).

Environment

  • mxcli v0.16.0 (darwin-arm64, macOS 15.6.1)
  • mx from Studio Pro 11.12.1 Beta (the bundled binary that mxcli docker check resolves
    on macOS)
  • Project version 11.12.1, MPRv2 storage format (mprcontents/ present)

Reproduction

Format oracle used throughout (1 = MPRv1 self-contained, 0 = MPRv2):

sqlite3 App.mpr "SELECT COUNT(*) FROM pragma_table_info('Unit') WHERE name='Contents';"

Starting from a clean MPRv2 project (oracle returns 0, mprcontents/ populated), each step
run against an isolated copy:

  1. Model writes via mxcli exec (alter page, create-or-replace page) → still v2. mxcli's
    own writer preserves the storage format.
  2. Plain mx check App.mpr (bundled binary, called directly) → still v2. The check is
    read-only.
  3. mx update-widgets App.mprv1. The oracle returns 1 and mprcontents/ is deleted.

mxcli docker check runs step 3 (as its "Updating widget definitions..." phase) before the
check, so the whole command reverts v2 → v1:

mxcli docker check -p App.mpr
# Updating widget definitions in App.mpr...
# Widget definitions updated.
# Checking project App.mpr...
# ...
# The app contains: 0 errors.

sqlite3 App.mpr "SELECT COUNT(*) FROM pragma_table_info('Unit') WHERE name='Contents';"
# 1   <- now MPRv1; mprcontents/ is gone

Impact

  • Silent storage-format change from a command named check.
  • On a Git project, HEAD and the working tree diverge, which can corrupt the repository
    state and (observed here) make Studio Pro unable to open the project.
  • The conversion is easy to miss: the check reports 0 errors and looks successful.

Suggestions

  • mxcli docker check should not leave the project in a different storage format than it
    found it. Either skip update-widgets, run it against a temporary copy, or convert back to
    MPRv2 afterwards.
  • At minimum, warn loudly when a check (or update-widgets) is about to rewrite the storage
    format, and skip it when the project is MPRv2.
  • Independently, mx update-widgets converting v2 → v1 looks like a platform-side surprise
    worth raising with Mendix; but mxcli can shield users from it in the docker check flow.

Workaround

Validate with the bundled mx check directly instead of mxcli docker check:

"/Applications/Mendix Studio Pro <ver>*.app/Contents/modeler/mx" check /abs/path/App.mpr

The trade-off is that skipping update-widgets can surface CE0463 widget-definition-drift
false positives, which then need to be judged by hand. If a project has already been
reverted, reopening it in Studio Pro converts it back to MPRv2 and regenerates
mprcontents/.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions