Sync ako/mxcli → upstream: TimeRegistration findings #51–#56 - #807
Merged
Conversation
…am-pr) Generating a cross-fork compare URL to merge ako/mxcli:main into mendixlabs/mxcli:main was a recurring manual task — mendixlabs/mxcli is not in tooling scope, so the PR can't be opened via API and we hand the user a prefilled compare link instead. - scripts/upstream-pr-link.sh: URL-encodes a title + Markdown body into a ?title=&body= compare URL. Defaults to ako/mxcli:main -> mendixlabs:main; --commits auto-builds the body from a git range; --body-file reads a hand-written body (stdin via -). Handles newlines/backticks/ampersands. - .claude/commands/mxcli-dev/upstream-pr.md: contributor slash command that wraps the script (draft title/body, generate link, present plain-text fallback, note the out-of-scope caveat). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
….9 (FINDINGS #39) A workflow whose flow contains a "call microflow" activity was written with the on-disk $Type `Workflows$CallMicroflowTask`. Both checkers passed (mxcli check ✓, mx check → 0 errors), but on an 11.9+ project the runtime refused to load the ENTIRE model at boot: Failed to load model: ... Class 'Workflows$CallMicroflowTask' could not be found Mendix 11.9 (WOR-2802) split MicroflowBasedActivity into CallMicroflowActivity + AIAgentTaskActivity, renaming the on-disk $Type. Evidence from the cached toolchains: the 11.6.3 modeler knows only CallMicroflowTask; the 11.10 modeler carries both (the old one marked "Removed due to code refactoring ... WOR-2802") plus a conversion routine; the 11.10+ runtime metamodel jars know only CallMicroflowActivity. The 11.9 boundary matches the existing HasOwner→HasOwnerAttr domain-model gate. Fix: emit CallMicroflowActivity for projects >= 11.9 and keep CallMicroflowTask for older ones. The semantic model is unchanged — only the emitted $Type differs — so the tree is built with the legacy name and rewritten when targeting 11.9+. - modelsdk (default engine): applyCallMicroflowStorageName walks the built element tree; useCallMicroflowActivityName() gates on pv.IsAtLeast(11,9). Codec TypeDefaults + list-marker registered under both $Type names. Wired into CreateWorkflow/UpdateWorkflow and the ALTER-workflow activity serializer. - legacy engine: renameCallMicroflowTypeBSON rewrites the serialized BSON, gated the same way in serializeWorkflow and SerializeWorkflowActivity. - read path already folds both gen types into the one semantic CallMicroflowTask. Tests: rename walk (both directions) + encode-validity under the new name; version gate against the vendored 11.6.6 fixture; legacy BSON-rewrite unit test. Repro mdl-examples/bug-tests/263-workflow-callmicroflow-storage-name.mdl; symptom row added to fix-issue.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…NGS LANGUAGE (FINDINGS #6) `alter settings LANGUAGE DefaultLanguageCode = '<code>'` accepted any string. A code not configured in the project (e.g. 'nl_NL' on an en_US-only project) was written, reported success, and the *next* `mx check` died with an unhandled NullReferenceException — never a model error, so the corruption was invisible until a later command. Validate the code against the project's configured languages (ps.Language.Languages) before writing; reject with the available codes and a Studio Pro hint. Skipped when the language list is unavailable (empty) to avoid false rejections. Verified end to end on the vendored fixture: 'nl_NL' rejected, 'en_US' accepted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…NDINGS #2) The lexer defined `V3: V '3';` (a "syntax version V3" marker) that no parser rule or visitor ever consumed — a dead token. Its only effect was to tokenize any bare `V3` in the input as the V3 token instead of IDENTIFIER, so `V3` was unusable as an attribute name, property name, or page binding while `V1`, `V2`, `V4`, `V5` (never tokens) all worked. Quoting (`"V3"`) was the only workaround. Removing the unused token lets `V3` tokenize as a normal IDENTIFIER. Verified: an attribute `V3 = 'c'` in a create activity and `Attribute: V3` in a page binding both parse, alongside the quoted form; grammar regenerated (`make grammar`); visitor and executor suites pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…41) A workflow `call microflow ... with (Name = ...)` mapping accepted a qualified (Mod.Flow.Param) or quoted ("Param") name via the QualifiedName grammar rule and stored its raw text. The executor then re-qualifies with `mfQN + "." + name`, so: - qualified input Mod.Flow.Param → stored Mod.Flow.Mod.Flow.Param → null ParameterId → runtime fails to load the model - quoted input "Param" → stored Mod.Flow."Param" → CE1613 - bare input Param → stored Mod.Flow.Param → correct Only the bare form worked — the one place MDL's "always quote identifiers" habit is actively wrong. Normalize the mapping name in the visitor to the bare, unquoted last segment so all three spellings converge on the correct single-qualified stored form. Verified end to end: bare, quoted, and fully-qualified inputs all store `MyFirstModule.ACT_Do.Item`. Unit test covers the normalizer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…c sugar, ADD doc (FINDINGS #3/#5/#13/#14/#4) Five surprising parser rejects / silent-wrong writes where quoting or a keyword behaved inconsistently with the rest of MDL: - #3 index name can't be quoted: indexDefinition accepted only IDENTIFIER for the name → `index "idx_x" (Col)` was a parse error. Accept QUOTED_IDENTIFIER too (the name is advisory and discarded, as before). - #5 role-name quoting inconsistent: DESCRIBE USER ROLE required quotes, DROP USER ROLE rejected them. Both now accept bare and quoted names; visitors handle both. - #13 `sort by` quoted attribute stored a nonsense reference: a quoted qualified attribute (`sort by "Mod"."Entity"."Code"`) kept the quotes and only failed on write ("attribute does not belong to entity"). buildSortColumnMicroflow now unquotes each segment (bare dotted form), matching the SORT() list-op path. - #14 `DataSource: ASSOCIATION $currentObject/…` didn't parse (keyword + sugar were mutually exclusive). Added the combined grammar branch; the existing VARIABLE&&SLASH visitor branch already handles it correctly. - #4 doc: MDL spec README showed `alter entity … add (Attr: type)`, which the parser rejects. Corrected to `add attribute Attr: type`. Grammar regenerated (`make grammar`). Verified end to end: quoted index name, quoted qualified sort stored as `M.Thing.Code`, describe/drop role in both forms, and `ASSOCIATION $currentObject/…` all parse/store correctly. Tests added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…ll gaps (FINDINGS #42/#36/#23/#48/#47) - #42 DESCRIBE WORKFLOW dropped the `with (...)` param mappings: the modelsdk read path built a CallMicroflowTask with only Microflow+Outcomes and never populated ParameterMappings, so describe→drop→exec silently lost the mapping (which nothing then reports). Added microflowParamMappingsFromGen and wired it into both the CallMicroflowTask and CallMicroflowActivity read cases; the legacy sdk/mpr parser already read them. Round-trip test added; verified `describe workflow` now emits `call microflow M.ACT_Do with (Item = '$workflowContext')`. - #36 SEC005 lint suggested `ALTER PROJECT SECURITY STRICT MODE ON`, a statement the parser doesn't implement. Strict mode is Studio Pro-only — the suggestion now says so instead of naming an unrunnable command. - #23 documented `create or modify association` (the idempotent form) in the domain-model skill: plain `create association` is not idempotent and its failure aborts the rest of the script. - #48 documented `set task outcome $Task '<Outcome>'` (there is no `complete task`) and the other workflow task statements in write-workflows. - #47 documented that System-module enumerations are read from the runtime, not the .mpr, so mxcli can't resolve them — constrain on an attribute instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…sociation (FINDINGS #51) A `create`/`change` activity assigning a one-qualifier member `Module.Name` that is not an existing association was written as an *attribute* reference. A one-qualifier name can never be a valid attribute (attributes are bare or Module.Entity.Attribute), so the result was an invalid AttributeIdentifier and the next `mx check` could not LOAD the project at all (StorageLoadException), even though `mxcli exec` reported success. This commonly followed a non-idempotent `create association` that had failed earlier in the script, leaving the association absent while a later `create` still referenced it — a green exec into an unloadable .mpr. In resolveMemberChange, when the domain model is available and a one-dot member is not found in the module's associations (or cross-associations), reject it with an actionable error ("create the association first ...") instead of serializing an Attribute. Associations created earlier in the same script are visible via GetDomainModel, so this does not false-positive on same-script associations; two-dot qualified attributes (Module.Entity.Attribute) are still allowed. Verified end to end: nonexistent association → clear error; same-script association → succeeds; qualified attribute → succeeds. Regression test + repro added; full executor suite (incl. cross-module association tests) passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
Mendix requires widget names to be unique per page and rejects duplicates with CE0495 "Duplicate name" — but `mxcli check --references` passed a page with, e.g., a container and a listview both named `ruTop`, and the failure only surfaced at MxBuild. Added checkDuplicateWidgetNames to the page context validator: it walks the widget tree, counts names, and reports each name used more than once (once per name, first-seen order). Runs at check time under --references, before the build. Verified end to end: a page with two `ruTop` widgets now reports the CE0495-class error; unique-named pages pass; full executor suite (no false positives on existing test pages). Unit + parsed-page tests added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
#40) A workflow "call microflow" activity that did not map a required parameter of its target microflow passed both `mxcli check --references` and `mx check`, but Studio Pro rejects it (CE6677) and the workflow fails at the activity — the mapped and unmapped forms were indistinguishable to the checker. Added a reference-phase validator (runs under --references, where the target microflow is introspectable): for each workflow call-microflow, look up the target microflow's parameters via ListMicroflows and report any parameter not present in the activity's `with (...)` mappings. Microflows created in the same script are skipped (not yet queryable); a target not in the project is left to the missing-reference check. Wired as a new CreateWorkflowStmt case in validateWithContext. Verified end to end: an unmapped `Item` parameter is now reported; the mapped form passes; full executor suite green. Repro mdl-examples/bug-tests/265-workflow-unmapped-microflow-param.mdl. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…ute values (FINDINGS #17) An aggregate (sum/count/average/…) or unknown function used inside a `create` or `change` attribute value fails the build with CE0117, but `mxcli check` only inspected return/if/declare/set expressions — the same MDL044 check never reached attribute-assignment values, so `RowTotal = formatDecimal(sum($cells), '0.00')` passed check and failed MxBuild with a message that didn't even mention `sum`. Wired checkExprFunctions (MDL044) into the CreateObjectStmt and ChangeObjectStmt cases of the microflow body walk. Verified: `sum()` in a create attribute now reports MDL044 with the "assign the aggregate to a variable first" hint; legit functions (formatDecimal/trim) pass; full executor suite green. Test cases added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…ize context var (FINDINGS #39 regression) The 11.9 storage-name fix (CallMicroflowTask→CallMicroflowActivity) let the runtime load the model again, but the retest found the new class also structures outcomes and the parameter-mapping expression differently — so a call-microflow with a parameter or a non-void return now failed `mx check` with two errors that the tolerant old class had passed: - CE6686 "outcomes do not match the configured microflow": autoBindCallMicroflow injected a single VoidConditionOutcome regardless of return type. The 11.9+ class requires outcomes that match the microflow — a Boolean return needs true/false BooleanConditionOutcomes. defaultCallMicroflowOutcomes now generates them from the target microflow's ReturnType (Boolean → two branches, else → single default). - CE0117 "Error(s) in expression": the context parameter is named "WorkflowContext" and 11.9+ expressions are case-sensitive, so a user-written `$workflowContext` (the form in every example) is an undefined variable. normalizeWorkflowContextExpr rewrites it to `$WorkflowContext`. Verified against real mxbuild on BOTH classes: - Mendix 11.12.1 (CallMicroflowActivity): `call microflow ACT with (Ctx='$workflowContext')` on a Boolean-returning microflow → 0 errors (was 2). - Mendix 11.6.3 (CallMicroflowTask): same script → 0 errors (no regression). Unit tests for both helpers; bug-test 263 updated to the param+Boolean-outcome case. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…tly dropping them
A `create page X { ...widgets... }` with no `Layout:` clause reported "Created page"
but produced an EMPTY page: buildPageV3 only builds a LayoutCall when Layout: is
present, and the widget tree is built into that LayoutCall's placeholder arguments —
so with no LayoutCall the widgets have nowhere to attach and were silently dropped.
Mendix then rejects the layout-less page at build with CE1613 ("layout
'dummyModule.dummyName' no longer exists" — its internal placeholder for a missing
layout). mxcli check passed; the widgets were simply gone — the same silent
data-loss pattern the TimeRegistration findings are about.
buildPageV3 now returns an actionable error when a page has body widgets (or
placeholder blocks) but no LayoutCall, distinguishing "no Layout: clause" from
"layout not found". Empty layout-less pages are unaffected (nothing to drop), and
snippets (buildSnippetV3) are layout-less by design and untouched.
Discovered while reproducing FINDINGS #49 (which no longer reproduces) against a
real Mendix 11.12.1 project + mx check. Unit tests (widgets→error, empty→ok);
repro mdl-examples/bug-tests/266; fixed the pre-existing no-layout page in the
ce0148 example. Symptom row added to fix-issue.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…9+ roundtrip) The 11.9+ write path emits `Workflows$CallMicroflowActivity`, but the legacy BSON parser only registered `Workflows$CallMicroflowTask`. On an 11.9+ project a written call-microflow activity read back as an unknown type, so DESCRIBE emitted the `-- [Workflows$CallMicroflowActivity] ...` fallback comment instead of `call microflow ... with (...)`. Register the new $Type against the same parser (it already reads Outcomes + ParameterMappings) so the activity round-trips on both pre- and post-11.9 projects. Fixes the integration failures TestRoundtripWorkflow_Comprehensive and TestRoundtripWorkflow_CallMicroflowWithParams on the 11.9.0 CI runner. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
… bindings (FINDINGS #55) ALTER PAGE INSERT/REPLACE into a ListView bound `from association` produced a widget whose Attribute binding pointed at the wrong entity — the outer data view's entity instead of the association's destination — or no binding at all. `mxcli check` passed; the Mendix build then failed with CE1613 "The selected attribute 'Module.OuterEntity.Attr' no longer exists", and DESCRIBE masked it by printing only the short attribute name. Root cause: the page mutator read the enclosing entity from DataSource.EntityRef.Entity, which is only populated for a DIRECT entity ref (database source). An AssociationSource stores its destination on the last DomainModels$EntityRefStep of an IndirectEntityRef, so the mutator saw no entity for the list and left the context at the outer data view's entity; the inserted bare attribute then resolved against that outer entity. Fix: extractEntityFromDataSource now also reads the IndirectEntityRef's last EntityRefStep.DestinationEntity (new lastStepDestinationEntity helper), so a list bound `from association` reports its correct child entity to INSERT/REPLACE. Verified on real mxbuild 11.12.1: the nested dataview→association-listview→insert and →replace cases now `mx check` with 0 errors (CE1613 before). Unit guard TestEnclosingEntity_AssociationSource; repro mdl-examples/bug-tests/55-alter-page-insert-assoc-binding.mdl. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…ore workflow-action describe (FINDINGS #51–54) Four findings from the TimeRegistration retest, all verified against real mxbuild 11.12.1: #53 — MDL048 rejected `retrieve … where [id = '[%CurrentUser%]']`, the standard signed-in-user idiom (mx check → 0 errors). checkXPathIdConstraint now skips a `'[%…%]'` server-token operand; a real stored-id value is still flagged. #52 — MDL045 rejected division whose divisor is an association-attribute path, e.g. `round($a div $obj/Attr * 100)`. The grammar parses div/*/`/` at one precedence level, so `$a div $obj/Attr` mis-nests as `($a div $obj) / Attr` with `Attr` a bare identifier; MDL045 saw the `/` as division. Mendix has no `/` division operator and re-parses the raw `$obj/Attr` as a path — the serialized output preserves the `/` and mx check passes. exprHasSlashDivision now ignores a `/` whose right operand is a bare IdentifierExpr (member navigation). #54 — `describe microflow` printed `-- Empty action` for `set task outcome` (and open user task / notify workflow) under the default modelsdk engine, so a describe→drop→exec round-trip silently dropped it. The write path and describe formatter already handled these; only the modelsdk read case (actionFromGen) was missing. Added SetTaskOutcome/OpenUserTask/NotifyWorkflow read cases. #51 — `create association` erroring on re-run is correct SQL-shaped semantics (not idempotent); the idempotent form `create or modify association` was undiscoverable. Improved the "already exists" error to name it (and `drop association …`). (#50 daysBetween sign and #52's dateTime-literal restriction are genuine Mendix platform behavior — the latter is already surfaced by MDL046 — so no code change.) Tests: TestValidateMicroflow_XPathIdConstraint (CurrentUser token), TestValidateMicroflow_SlashDivision (div-by-assoc), TestActionFromGen_WorkflowActions. Repros: mdl-examples/bug-tests/{52-53-microflow-check-false-positives,54-describe-set-task-outcome,51-create-or-modify-association}.mdl. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
`bun install` floats typescript to ^6.0.2, which no longer auto-includes
every `@types/*` package on disk — `types` must be listed explicitly.
Without it tsc reported 43 errors on a clean checkout (`process`,
`console`, `setTimeout` unresolved, plus the implicit-any fallout on
node callbacks), so `make lint` failed before any change was made.
- tsconfig.json: declare `"types": ["node", "vscode"]`
- extension.ts: create the output channel with `{ log: true }` so it is a
`LogOutputChannel`, which is what vscode-languageclient 10's
`LanguageClientOptions.outputChannel` requires
CI only runs `make lint-go`, which is why this went unnoticed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
…ERT/REPLACE bindings (FINDINGS #55) Retest of #55 showed the association + database datasource cases are fixed, but a microflow/nanoflow datasource still bound nothing: inserting/replacing a data-bound widget in a list bound `datasource: microflow …` produced an unbound attribute (mx check CE0402 "No value specified" / CE1613). Unlike a database (direct EntityRef) or association (IndirectEntityRef) source, a MicroflowSource/NanoflowSource stores no entity in its own BSON — the entity is the flow's RETURN type, which lives in the flow document. So the mutator's BSON walk yielded "" and the bare inserted attribute resolved against nothing. Fix: the page mutator's new EnclosingDataSourceFlow returns the qualified name of the microflow/nanoflow governing the target's context — the nearest ENCLOSING datasource for sibling INSERT/REPLACE, or the widget's OWN datasource for INSERT INTO — via findNearestDataSourceDoc, which returns the nearest datasource *doc* so a nearer non-flow source (database/association) correctly shadows an outer flow. The executor (resolveDataSourceFlowEntity) then resolves that qualified name to the flow's return entity via the existing getMicroflowReturnEntityName / getNanoflowReturnEntityName, and uses it as the widget's entity context when the BSON walk found none. Verified on real mxbuild 11.12.1: INSERT and REPLACE into a microflow-sourced ListView now mx check with 0 errors (CE0402 before). New EnclosingDataSourceFlow interface method + mock/mcp impls (mcp is a no-op — its model resolves entities directly). Unit guard TestEnclosingDataSourceFlow (incl. nearer-source shadowing); repro extended in mdl-examples/bug-tests/55-alter-page-insert-assoc-binding.mdl. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…em (mendixlabs#801) ALTER SETTINGS — any section, not just CONFIGURATION — serialized every ServerConfiguration from the semantic model, which carries only the fields mxcli understands. Everything else in the stored document was therefore silently deleted on write: - CustomSettings replaced with an empty array - Tracing replaced with null - OpenAdminPort / OpenHttpPort reset to false (the reader never populates them, so the model always held the zero value) - the Configurations / ConstantValues / CustomSettings version markers downgraded from 3 to the hardcoded 2 - constant overrides rewritten with a flat "Value", the shape Studio Pro and mxbuild ignore — so after one ALTER SETTINGS every override looked empty in Studio Pro, and Integer/Long constants failed the build The configurations are now overlaid onto the raw document they were read from (ADR-0005 guard-don't-drop, which the surrounding settings parts already followed): only fields the read path populates are written, each list keeps its stored marker, and a constant override is updated in the slot it already occupies so a nested SharedOrPrivateValue survives. A new override — which has no stored shape to preserve — is written nested, since that is what the platform reads. A configuration created by CREATE CONFIGURATION takes its shape from a sibling, with the per-configuration collections emptied and a fresh $ID. The overlay lives in mdl/settingsoverlay because both write engines had the same bug in duplicated form; sharing it keeps the codec engine (mdl/backend/modelsdk) and the legacy engine (sdk/mpr) from drifting again. Also refuse the write outright when no raw parts were captured on read: that path would have replaced every settings part with an empty array. Known limitation: a project whose overrides were already flattened by an earlier mxcli run keeps the flat shape, since the overlay preserves what is stored rather than converting it. Those overrides need to be re-entered in Studio Pro once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
…endixlabs#805) `alter settings configuration 'Default' HttpPortNumber = 'not-a-number'` printed "Updated configuration 'Default'" and changed nothing. Every Integer-typed setting parsed its value with the error discarded — `if v, err := strconv.Atoi(valStr); err == nil` — so an unparseable value skipped the assignment while the handler still reported success. DESCRIBE SETTINGS then showed the original value. The boolean settings had the same hole in a different form: `AllowUserMultipleSessions = valStr == "true"` mapped every other spelling, including a typo or a plausible 'yes', to false and reported success. Both now parse through helpers that return a validation error naming the setting and the offending value, so nothing is written. Covers all seven sites: BcryptCost, AllowUserMultipleSessions, DefaultTaskParallelism, WorkflowEngineParallelism, and HttpPortNumber / ServerPortNumber on both ALTER SETTINGS CONFIGURATION and CREATE CONFIGURATION. The same values are now reported at check time too (MDL-SET01 integers, MDL-SET02 booleans), wired into `mxcli check` and the LSP so a typo surfaces before the project is opened for writing. TestTypedSettingsKeys_MatchExecutor guards the check-time table against drifting from the executor's assignment switch. Out of scope: range validation. A port of 0 or 999999, or a negative BcryptCost, still parses as an integer and is accepted, as before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
…ct arg (write is correct) Investigation of FINDINGS #56 ("describe page omits a show_page action's arguments"), verified against mxbuild 11.12.1: A widget button's show_page stores FormSettings.ParameterMappings as an empty list [2] and Mendix infers the current-row object for each unmapped page parameter. Storing an explicit `Argument: "$currentObject"` mapping makes mxbuild report CE0115 "arguments do not match" — the original issue mendixlabs#296, re-confirmed here. So the empty-mapping write is REQUIRED for a building app. Consequence: `show_page X` and `show_page X($p = $currentObject)` serialize to identical BSON, so describe→drop→exec re-produces a byte-identical valid page — the round-trip is functionally lossless; only the redundant $currentObject annotation is not echoed. No writer change (a fix there reintroduces CE0115); clarified the serializer comment and added a bug-test documenting the verified behavior and the boundary (a non-$currentObject widget page arg needs a Studio-Pro WidgetValue reference to encode). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
fix(settings): stop ALTER SETTINGS dropping configuration data and silently ignoring invalid values
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 the latest batch of fixes from
ako/mxcli:main(validated against a real Mendix project,ako/mxcli-timeregistration). Every fix was verified against mxbuild 11.12.1 (mx check→ 0 errors), and each ships with a regression test, anmdl-examples/bug-tests/repro, and afix-issue.mdsymptom row.ALTER PAGE — attribute bindings on non-database datasources (#55, closes remaining #49)
from associationordatasource: microflow/nanoflowbound the widget's attribute to the wrong entity (or nothing) —mxcli checkpassed but the build failed CE1613 / CE0402.EntityRefStepof theIndirectEntityRef. Microflow/nanoflow: the source stores no entity (it's the flow's return type), so the mutator now reports the governing flow's qualified name (EnclosingDataSourceFlow, with a nearer non-flow source shadowing an outer flow) and the executor resolves its return entity.Microflow check false-positives
[id = '[%CurrentUser%]']— the[%…%]server token is a valid, build-clean id operand; real stored-id values are still flagged.round($a div $obj/Attr * 100)); a/with a bare member-name right operand is navigation, not division.DESCRIBE round-trip
set task outcome/open user task/notify workflowmicroflow actions instead of rendering-- Empty action, so describe→drop→exec no longer drops them.Diagnostics / docs
create associationon re-run now names the idempotent form (create or modify association …) in its error.show_page's$currentObjectargument is intentionally not stored — Mendix infers it, and storing it explicitly triggers CE0115 — so the describe→exec round-trip is functionally lossless.Platform-only, no code change: #50 (
daysBetweensign) and #52'sdateTime()-literal restriction (already surfaced by MDL046).