Repository navigation
Sync ako/mxcli: 18 reported-issue fixes (check/exec parity, describe round-trips, Mendix 9 JDK) - #1448
Merged
Conversation
…s#1431) Reported: "`mxcli check -p R/R.mpr bad.mdl good.mdl` ... the final line is 'Check passed!' even though the exit code is 1"; reversing the file order flips the last line, so anything reading the log tail sees success. runCheckFiles kept only the worst exit code; each file printed its own verdict and nothing printed one for the set. It now closes with "N of M files failed: a.mdl, b.mdl" or "All M files passed". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: "`mxcli marketplace download <id> --output <existing dir>` ... fails with a rename error reading `rename ... file exists`". The temp file was created in filepath.Dir(output) and renamed onto output itself. An --output that is an existing directory, or ends in a separator, now gets the temp file inside it and the package written as <dir>/<CDN filename> (or the content-<id>-<ver>.mpk fallback). Flag help says "file or directory". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: `mxcli describe rule PgVectorKnowledgeBase.Rule_...` answers "Unknown type: rule", although `show rules` lists 14 and the MDL statement `describe rule ...` is handled by the executor. The describe subcommand keeps its own copy of the DESCRIBE type list (describeMDLCommand) and two auto-detect maps; none of them knew rules, so the explicit form was refused and the bare `describe Mod.Rule` form found "no describable document". Add RULE -> DESCRIBE RULE, catalog ObjectType RULE and unit type Microflows$Rule -> rule, and list rule in the help and the Valid types line. The "which is not a rule in this project" refusal from the same report is a downstream effect and is left alone. Test: TestDescribeMDLCommand_Rule (cmd/mxcli). Control: with the fix reverted it fails with "describe rule M.R: Unknown type: rule". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…endixlabs#1442) Reported: `marketplace install` on a module already in the project says updates are "NOT done automatically" and hands the user off to Studio Pro, in a container that has none; `mxcli marketplace update` exists. Install still refuses to update implicitly, but now prints the concrete `mxcli marketplace diff <id> -p <mpr> --to <ver>` and `mxcli marketplace update <id> -p <mpr> --to <ver>` commands (placeholders for a --file install, which has no content id). Long help and the marketplace guide / capabilities table say the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: "`describe module ... with all` truncates at 10 000 lines without a warning" — "output stops in the middle of a statement", exit 0. The per-statement output guard returns an error from Write once it passes maxOutputLines and discards everything after, but describers ignore Fprintf's error, so the handler returned nil and Execute never looked at the guard. Execute now returns the limit error when the statement otherwise succeeded but the guard was exceeded; the message says the output was truncated and suggests describing per document. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…nt (mendixlabs#1412) Reported: describe java action prints `Name: String not null -- This sets the Name of the tool...,` "the comma lands inside the comment, so the next parameter is a syntax error" -- mxcli check of the output fails with `line 255:4 mismatched input 'Name' expecting ')'`. The parameter loop wrote ", " at the start of the next iteration, i.e. after the previous parameter's trailing `-- doc` comment. The JavaScript action describer carries the same loop and the same bug. Both now write the separator at the end of each non-final parameter, before the comment. Test: describe -> visitor.Build round trip for a Java and a JavaScript action with documented parameters; both fail with the fix reverted (`mismatched input 'Amount' expecting ')'`). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…endixlabs#1438) Reported: `alter settings runtime ( JavaVersion: '17' );` on a Mendix 9.24 model printed "Unchanged model settings" -- no hint that the property does not exist in that version. refuseIfNotStored exempted JavaVersion unconditionally because it is stored under either JavaVersion or JavaMajorVersion. A 9.x document carries neither, and settingsoverlay.SetJavaVersion writes nothing when JavaVersionKey(raw) is empty, so the statement was a silent no-op. Exempt only when one of the keys is present; otherwise refuse, saying the setting does not exist on this Mendix version and the JDK is chosen by the platform. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…labs#1413) Reported: `check` ends with `Check passed!`, but `exec` refuses $Sum = sum $List by Amount; set $Sum = $Sum + 1; with "variable 'Sum' is not declared" (same for `$N = count $List`). The validate pass declared an AggregateListStmt's output; addAggregateListAction, which exec runs, never registered it, so the SET's declared-variable check failed only at exec. It now declares the result: count Integer, average Decimal, all/any Boolean, reduce its declared return type, and sum/min/max Unknown (their type follows the attribute, which is not resolved here). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: `expose (Name as 'Name' (KEY), "Description")` passes check and exec, then mx check fails with [CE1613] "The selected attribute 'ModA.EntA."Description"' no longer exists." and describe prints `"Description" as '"Description"'`. parseExposeMembers and the publish-microflow expose loop read IdentifierOrKeyword().GetText(), which keeps a QUOTED_IDENTIFIER's quotes. Use identifierOrKeywordText, as every other name slot in the file does. After the fix the repro describes as `Description as 'Description'`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…#1435) Reported: `mxcli describe module Banking -p <banking>.mpr` prints only `mdl 1; create or modify module Banking; create or modify module role ...` although the help says "Describe a module (all contents)"; the full emitter needs `-c "describe module Banking with all"`, which is documented only in the changelog. Choice: add an opt-in `--all` flag (DESCRIBE MODULE ... WITH ALL) and fix the help, rather than appending WITH ALL to every describe module. - A plain describe module matches what `-c "describe module X"` prints, so the subcommand and the MDL statement keep one meaning. - Scripts that describe a module for its header and roles keep working. - WITH ALL has open gaps: mendixlabs#1421 (omits document types) and mendixlabs#1425 (truncates at 10k lines without saying so). Making it the default would swap a wrong help line for output that is silently incomplete. `--all` on any other type is refused rather than ignored. Test: TestDescribeModule_HelpMatchesOutput (cmd/mxcli). Control: with the pre-fix help and a pass-through stub it fails with `describe --help promises "all contents" for a plain describe module` and `describe has no --all flag`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
`list java actions in System` listed System.VerifyPassword, but
describe java action System.VerifyPassword
Error: java action not found: System.VerifyPassword
and exec of a microflow calling it logged
warning: could not look up Java action System.VerifyPassword: java
action not found: System.VerifyPassword (entity type params will be empty)
ReadJavaActionByName only scanned stored units, and resolved the module
first, which fails for System (no stored module unit). The System built-ins
are virtual and were synthesized on the list paths only. Fall back to
meta.BuildSystemJavaActionsFull by name when the module is System and no
stored unit matches; stored units still win, unknown System.X stays
not found.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: `mxcli run --local --db-type hsqldb` against a Mendix 9.24 app, with JAVA_HOME pointing at JDK 17, fails in mxbuild's Gradle 7.6 with "Unsupported class file major version 65" -- mxcli resolved JDK 21 even though JAVA_HOME is 17, and a 9.x model has no JavaVersion setting to steer the choice. ProjectJavaMajor fell back to DefaultJavaMajor (21) whenever the model stores no JavaVersion, which is always the case on 9.x, so resolveJDK skipped the JDK 17 JAVA_HOME. Derive the fallback from the project's Mendix version instead: 9.x -> 17 (9.x supports Java 11 and 17; 9.24 LTS uses 17), 10.x/11.x -> 21 as before. Also stop the JDK-not-found error suggesting `alter settings runtime ( JavaVersion: '21' )` below the default: on 9.x that statement changes nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: "`describe user role` omits `CheckSecurity` when it is `false`", so the replay re-creates the role with the default -- "Silent security change on replay (round-trip drift)". Expected: the output carries `CheckSecurity: false`, as `show user roles` reports it. formatUserRoleMDL printed CheckSecurity only when true, but a new role is written with true (Security$UserRole.CheckSecurity defaults to true), and `create or modify` keeps an unstated stored value, so false was lost both on recreate and on replay onto an existing role. It is now always printed. The executor mock's AddUserRole built roles with Go's zero CheckSecurity, which hid this from the #707 round-trip test; it now mirrors the real writer's default. Test: TestIssue1427_UserRoleCheckSecurityFalseSurvivesReplay fails before the fix ("recreated role has CheckSecurity true, want false", "modified role kept CheckSecurity true, want false"). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
) Reported: describe emits `content { }` for native pluggable-widget child slots (Repeater, SafeAreaView); check then fails with "`content` is not a container of `repeater` — it declares: template [MDL-WIDGET26]" and exec with "content needs a name". The widget definition names a widgets-typed slot with mdlContainerForWidgetSlot (content -> TEMPLATE); describe's extractChildSlots used deriveObjectListKeyword, the object-list convention, which leaves `content` unchanged. Describe now calls the same function as the definition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…xlabs#1419) Reported: a script that creates image collection ModA.Icons and then a page with `image img1 (Image: 'ModA.Icons.pix')` fails check with image collection not found: ModA.Icons (referenced as ModA.Icons.pix) and exec with "Refusing to execute: 1 unresolved reference(s) above. Nothing was written." Split into two scripts, it passes. validateWidgetReferences resolved image references against the project only, under a stale comment saying MDL cannot create an image collection. scriptContext now records the collections and images that CreateImageCollectionStmt declares, and they are merged into the project sets (only when those could be read, so a failed read still reports nothing). An undeclared image in a script-created collection is still reported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…ity (mendixlabs#1430) Reported: `$L = sort $BookChunkList by Similarity desc;`, where Similarity is declared on the generalization, fails in mxbuild with CE1613 "The selected attribute 'Embeddings_SemanticSearch.BookChunk.Similarity' no longer exists." The list-operation sort prefixed a bare attribute with the list's own entity. The retrieve `sort by` path already resolves the declaring entity through resolveAttributeInEntityHierarchy; the list sort now does the same, falling back to the list entity when the model does not resolve the name. FIND/FILTER already qualify through resolveMemberChange, which walks the hierarchy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…s#1436) For create or modify microflow M.F () returns Boolean as $Closed begin $Closed = true; return $Closed; end; `$Closed = true;` was refused with "a reassignment says `set` under mdl 1: write `set $Closed = true;`", and `set $Closed = true;` then with "variable 'Closed' is not declared" - each message sent the reporter to the other. The semantics are right and unchanged: `as $X` names the result for callers and declares nothing. Messages only: - the mdl 1 "use set" error also offers `declare $X <Type> = …;` for a variable that is new; - the not-declared error on `set $X`, when $X is the flow's `returns … as` name, says the clause does not declare it and shows the declare with the return type. validateFlowBody now receives the return type for this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…s mx check Without it mx check fails CE6624 (an OData key attribute needs a unique validation rule), which hid whether the CE1613 from the quoted name was gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…lists The separator fix makes these JavaScript actions' describe output parse again, so integration (roundtrip) failed with "no longer breaks parse — strike it from knownFailures … The allowlist may only shrink" for each of them, on both PedApp and TestApp. All 14 entries listed lawParse only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: fail a statement whose output hit the line limit (mendixlabs#1425)
fix: declare an aggregate's output variable in the build pass (mendixlabs#1413)
fix: unquote quoted names in OData expose clauses (mendixlabs#1423)
…curity fix: describe user role always states CheckSecurity (mendixlabs#1427)
fix: qualify a list sort's inherited attribute with its declaring entity (mendixlabs#1430)
fix: resolve System Java actions by name (mendixlabs#1445)
) Reported: "Exec writes an import-mapping microflow with a null entity and the `.mpr` can no longer be loaded" — a microflow calling `import from mapping X` above `create import mapping X` passed check and exec, then mx check failed loading the project with "Value cannot be null. (Parameter 'value')" in EntityType.set_EntityId. The flow builder dropped the mapping lookup error and stored the activity with VariableType.Entity = "". Fixed at three layers: - builder: an unresolved mapping, or one without a root entity, is a statement error instead of an empty result entity; - MDL-ORDER01 (no-project and project tiers) gains an "import mapping" kind, so check reports the forward reference before anything is written; - writer: CreateMicroflow / UpdateMicroflow and the splice's SerializeObject refuse an import activity with no result entity (loop bodies included). A project already written by the old bug was not repaired by re-running the statement: describe prints the broken activity as exactly the statement that would fix it, so create or modify reported "Unchanged microflow". A stored import activity without a result entity is now not spliceable: mdl 0 rebuilds the flow (healing it), mdl 1 refuses with the drop-and-create advice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: run --local picks JDK 17 for a Mendix 9 project (mendixlabs#1437)
fix: resolve image refs against collections the script creates (mendixlabs#1419)
…ndixlabs#1410) Reported: microflows and nanoflows cannot be created or altered in a 9.x project — Error: failed to create microflow: unit …: this Mendix 9.24.2 project cannot store Microflows$Microflow.StableId (Mendix 10.2.0+); Microflows$SequenceFlow.CaseValues (Mendix 10.15.0+) (also CreateNanoflow and ALTER MICROFLOW; 10.0–10.14 for CaseValues alone). Same root cause as mendixlabs#1434, whose repro is an empty microflow on 9.24.2. The flow writers emitted the newest shape whatever the version. The property floor (e671bec) rightly refuses the two keys that hold a value; before it they were written silently, and forcing that shape back onto 9.24 is 8 errors in mx check (CE0079/CE0773: the decision's cases are not read). Gated on major.minor (flowVersion), with the Model SDK's StructureVersionInfo (mendixmodelsdk 4.116.0) as the floors and the shapes measured from a Studio Pro 9.24.30 document and the same document after `mx convert` to 10.12.19: - Microflow.StableId only from 10.2 (encoder OmitKeys, which now also applies to registered type defaults); on >= 10.2 it is emitted and carried as before - the case as one NewCaseValue below 10.15, a CaseValues list from 10.15 (gen bound the single case as "CaseValue"; overridden to its storage name) - Origin/DestinationBezierVector below 10.16 (+ LineType "BezierCurve" from 10.8), the BezierCurve Line from 10.16 — sequence and annotation flows; the reader takes the vectors from either shape - ReturnVariableName from 10.12, parameter IsRequired/DefaultValue from 10.17 (both were written on any 10.x; the floor cannot see them) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: refuse alter settings JavaVersion on a model that stores none (mendixlabs#1438)
fix: end a multi-file check on a verdict for the whole set (mendixlabs#1431)
fix: describe child slots with the definition's keyword (mendixlabs#1400)
fix: wire rules into the describe subcommand (mendixlabs#1402)
…ule-all # Conflicts: # cmd/mxcli/cmd_describe_test.go
…t-dir fix: marketplace download --output accepts a directory (mendixlabs#1443)
fix: explain `returns … as $X` in the set/declare messages (mendixlabs#1436)
fix: describe code action writes param separator before its doc comment (mendixlabs#1412)
…ace-update fix: install names `marketplace update` for a module already present (mendixlabs#1442)
fix: refuse import from mapping without a result entity (mendixlabs#1418)
fix: add describe --all and make the module help truthful (mendixlabs#1435)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: write flows in the shape each Mendix 9/10 version declares (mendixlabs#1410)
AI Code ReviewWhat Looks GoodThis PR successfully syncs 18 reported-issue fixes and 2 test follow-ups from the ako/mxcli fork. The changes are well-scoped, each addressing a specific issue with corresponding test coverage. Key improvements include:
All fixes include:
RecommendationApprove the PR. The changes are correct, well-tested, and maintain consistency with the project's architecture and guidelines. No issues were found during review against the checklist. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
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.
Syncs
ako/mxcli:mainintomendixlabs/mxcli:main: 20 commits since #1447, landed in the fork through PRs ako#1140–ako#1157. Eighteen fix a reported issue; two are test follow-ups.check / exec agree
checkends on a verdict for the whole set: "N of M files failed: …" or "All M files passed" (Set-modecheckprints "Check passed!" after an earlier failure in the same invocation #1431). The last line used to be the last file's verdict, so a log tail could read "Check passed!" with exit code 1.seton a variable created by an aggregate activity (sum/count), which describe emits #1413).$Sum = sum $List by Amount; set $Sum = …passed check and failed exec.returns … as $X: the set/declare messages now explain how the return variable is declared (RETURNS Boolean AS $Closeddoes not declare$Closed; both obvious forms are refused with confusing messages #1436). Before, each message sent the author to the other spelling.import from mappingwithout a result entity is refused (Exec writes an import-mapping microflow with a null entity and the.mprcan no longer be loaded #1418), instead of writing a microflow mx check could not load ("Value cannot be null").describe module ... with alltruncates at 10 000 lines without a warning #1425).describe round-trips
describe user rolealways statesCheckSecurity(Describe userrole dropsCheckSecurity: false#1427). Afalsevalue was lost on replay, a silent security change.--comment #1412). Java and JavaScript actions are affected; 14 JavaScript actions leave the roundtrip allowlists.template, notcontent) (Describe emitscontent { }for native pluggable-widget child slots that are namedtemplate#1400).exposeclauses are unquoted (Published ODataexpose ("Description")stores the quotes in the attribute name #1423), where they were CE1613 at build time.describe subcommand
mxcli describe(Rules cannot be described or created #1402).mxcli describe module --allgives the full emitter, and the module help now says what a plain describe prints (mxcli describe module <M>subcommand emits only the module and its roles #1435).describe java action System.VerifyPasswordworks, and exec no longer warns (System Java actions are unknown to mxcli #1445).Mendix 9 and settings
run --localpicks JDK 17 for a Mendix 9 project (mxcli run --localcannot run a Mendix 9 app #1437). A 9.x model stores no JavaVersion, so the default of 21 was used and Gradle 7.6 failed.alter settings runtime ( JavaVersion: … )on a model that stores none is refused with an explanation, instead of printing "Unchanged" (alter settings runtime ( JavaVersion: '17' )on a 9.x model printsUnchanged model settings#1438).Marketplace
marketplace download --outputaccepts a directory (marketplace download <id> --output <dir>fails; only a file path works #1443).marketplace installon a module already present names themarketplace diff/updatecommands, instead of sending the user to Studio Pro (No headless update for a marketplace module already in the project #1442)