Skip to content

fix(pages): flow-argument mappings crash Studio Pro's Changes panel and bind the wrong slot (mendixlabs/mxcli#1317) - #1008

Merged
ako merged 5 commits into
mainfrom
claude/mxcli-issue-1317-ia1eiw
Oct 7, 2026
Merged

ako merged 5 commits into
mainfrom
claude/mxcli-issue-1317-ia1eiw

Conversation

@ako

@ako ako commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Fixes mendixlabs#1317.

Reported symptom

After alter page LearningJourney.LearningJourney_Details { set ('onClickAction': call microflow LearningJourney.ACT_ExcludeItemStep(LearningJourney = $LearningJourney)) on pDSLink_ButtonAndTracking8 }; on Studio Pro 11.12.2, opening the change in the Changes panel throws:

System.InvalidOperationException: Objects with ID [redacted] of type Forms$MicroflowParameterMapping do not have the same properties. baseNames = Expression, Parameter, Variable; newNames = Parameter, Expression

Three defects (five commits)

  1. Variable key omitted on an Expression-bound argument (the crash). Studio Pro writes Expression, Parameter and Variable on every Forms$MicroflowParameterMapping / Forms$NanoflowParameterMapping, with the unused slot set to null. mxcli left Variable unset, and the encoder drops an unset part. Because the stored $ID is carried onto the rewritten mapping, the merge library sees one element in two shapes. Same class as Studio Pro crashes when opening Changes details after ALTER ENTITY ... MODIFY ATTRIBUTE mendixlabs/mxcli#1180.
    Fix: register Variable as a NullFields default on both types (mdl/backend/modelsdk/widget_write.go). This covers every writer: actions, nanoflow actions and nanoflow data sources.
  2. alter page … set built the action with an empty parameter scope. So $LearningJourney, a page parameter, was stored as the Expression "$LearningJourney" instead of Variable → Forms$PageVariable. That is the Page parameter not wired in nanoflow argument when button is inside a dataview bound to a different parameter CE1571 mendixlabs/mxcli#1140 form, which Studio Pro does not bind (CE1571).
    Fix: convertASTAction seeds paramScope, page variables and isSnippet from the mutator, as insert/replace already did.
  3. alter snippet … insert/replace bound a snippet-parameter argument as a page parameter. buildWidgetsFromAST / buildColumnSpecsFromAST never set isSnippet.
    Fix: set it from mutator.ContainerType().

Evidence

Tests written first:

  • widget_flow_param_null_variable_test.go: failed with mapping keys = Expression, Parameter.
  • TestAlterPage_SetNamedAction_PageParamBindsThroughVariable: failed with kind "".
  • TestAlterSnippet_InsertedFlowArgBindsSnippetParameter: failed with kind "parameter". Its page-container control passes both ways.

Reverting fix 1 made its test fail again with the reported key set.

Real tool, mxbuild 11.12.2, buggy and fixed builds side by side:

Defect Check Buggy build Fixed build
1 mx diff base.mpr new.mpr out.mpr (same comparison code as the Changes panel) exit 129, Objects with ID … of type Forms$MicroflowParameterMapping do not have the same properties. baseNames = Parameter, Expression, Variable; newNames = Parameter, Expression exit 0
2 bson dump of the mapping Expression: "$LearningJourney", no Variable Variable: Forms$PageVariable{PageParameter: "LearningJourney"}; the literal argument carries Variable: null
3, inserted widget mx check 1 error: [CE0115] … at Action button 'btnInsert' 0 errors; created, inserted and set buttons all bind SnippetParameter
3, inserted grid column mx check 1 error: [CE0115] … at Action button 'btnCol', binding PageParameter: "Order" 0 errors, binding SnippetParameter: "Order"

mx check reports 0 errors for defects 1 and 2 on both builds, so a build does not catch either.

Not verified

  • I didn't open Studio Pro's Changes panel itself; mx diff stands in for it. My baseline was written by the fixed build, which writes the same three-key shape as Studio Pro.

Regression coverage

  • mdl-examples/bug-tests/1317-flow-arg-mapping-null-variable.mdl
  • mdl-examples/bug-tests/1317-alter-snippet-insert-flow-arg.mdl: the inserted widget and the inserted grid column. The whole file runs on a fresh 11.12.2 project at 0 errors.
  • Findings appended to mdl-backend.jsonl and mdl-executor.jsonl. The main point: mx diff reproduces Changes-panel crashes without Studio Pro.
  • make build, make test, make lint, make check-mdl and make check-findings all pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr

claude added 4 commits October 6, 2026 19:25
Studio Pro writes Expression, Parameter and Variable on every
Forms$MicroflowParameterMapping / Forms$NanoflowParameterMapping and nulls
the unused slot. An Expression-bound argument left the gen Variable part
unset, so the encoder omitted the key, and opening the change in Studio
Pro's Changes panel threw "do not have the same properties. baseNames =
Expression, Parameter, Variable; newNames = Parameter, Expression".

Register Variable as a null field on both types, which covers the action,
nanoflow action and nanoflow data-source writers alike.

Refs mendixlabs#1317

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
convertASTAction built its pageBuilder with no parameter or variable scope,
so `set (Action: call microflow M.F(P = $P))` and a pluggable widget's
named action slot wrote a page parameter as the Expression "$P" rather
than binding it through Variable -> Forms$PageVariable (the mendixlabs#1140 form,
which Studio Pro does not resolve). Seed it from the mutator as
INSERT/REPLACE already do, including isSnippet.

Refs mendixlabs#1317

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
Regression MDL for mendixlabs#1317 and the finding: `mx diff`
reproduces Studio Pro Changes-panel crashes headless.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
…pet parameter

buildWidgetsFromAST and buildColumnSpecsFromAST seeded the stored parameter
scope but never isSnippet, so a button inserted into a snippet with
`call microflow M.F(P = $P)` wrote Forms$PageVariable.PageParameter
instead of SnippetParameter. mxbuild 11.12.2 reports CE0115 on that button
only; CREATE SNIPPET and ALTER SNIPPET SET were already correct. Set
isSnippet from the mutator's container type, as convertASTAction does.

Refs mendixlabs#1317

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
@ako ako changed the title fix(pages): write Variable: null on an Expression-bound flow argument fix(pages): flow-argument mappings crash Studio Pro's Changes panel and bind the wrong slot (mendixlabs/mxcli#1317) Oct 7, 2026
…labs#1317 snippet case

The isSnippet fix also reaches buildColumnSpecsFromAST. Add a column with a
flow button inserted into a grid inside a snippet. Measured on mxbuild
11.12.2: before, PageParameter and CE0115 at the button; after,
SnippetParameter and 0 errors.

Refs mendixlabs#1317

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
@ako
ako merged commit 764a6d9 into main Oct 7, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants