fix: preserve stored widget property metadata on ALTER PAGE REPLACE (CE0463) - #797
fix: preserve stored widget property metadata on ALTER PAGE REPLACE (CE0463)#797ront85 wants to merge 1 commit into
Conversation
…loses mendixlabs#112) Replacing a pluggable widget emitted Type metadata (per-property Caption/Category) generated from the embedded template and installed .mpk, while untouched sibling widgets in the same page unit carried metadata from whichever widget version authored them in Studio Pro. MxBuild flags the mixed vintages as CE0463 on the rebuilt widget, even for an identity rebuild that changes nothing. ReplaceWidget now grafts the stored widget's per-property display metadata (Caption, Category, Description) onto the replacement's freshly generated Type block: - matched by slash-joined PropertyKey path, not flat key, so distinct nested object types that reuse a key (e.g. markers/latitude vs dynamicMarkers/latitude) stay independent - only onto replacements of the same WidgetId, including pluggable widgets nested inside container replacements - leaf display fields only; $IDs and ValueTypes are never copied, so the new widget's Object/Type cross-references stay intact Verified against a Mendix 11.12.2 MPRv2 project with Combobox v2.8.1: identity rebuild and datasource-XPath replace both now pass docker check with zero errors (previously CE0463 on both). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Update: I re-tested both repros in this PR against unpatched Root cause: #8a14fc2d ("reconcile ComboBox definition drift generically — close #112 CE0463", merged 2026-07-20) made the freshly-emitted I no longer have a reproducible failure on current main for the scenarios in this PR's description. I'm going to hold off on merging this until I can find a case 8a14fc2 doesn't cover (if one exists) — will update or close depending on what I find. Apologies for the noise; posting this rather than leaving a possibly-redundant PR silently open. |
Problem
Any
ALTER PAGE … REPLACEof a pluggable widget produces CE0463 ("The definition of this widget has changed…") on the rebuilt widget — even an identity rebuild that changes nothing:mxclireports success andmxcli check --referencespasses; only a real MxBuild check catches it. This blocks the whole class of "adjust an existing pluggable widget" edits (e.g. adding an XPath constraint to a combobox datasource). Reproduced identically on v0.13.0 and v0.16.0 against a Mendix 11.12.2 MPRv2 project with Combobox v2.8.1.Root cause
The rebuild emits
CustomWidgets$WidgetPropertyTypemetadata generated from the embedded template + installed.mpk, while untouched sibling widgets in the same page unit carry metadata from whichever (older) widget version authored them in Studio Pro. A byte-level diff of the page unit before/after an identity rebuild showed exactly two divergences, both per-property display metadata:filterInputDebounceInterval→CategoryAdvanced::FilterEventsonChangeEvent→CaptionOn selectionOn changeA rebuilt widget and its neighbours end up described by two different widget versions in one file, and MxBuild rejects the mix.
Note on #112 (closed): its stated root cause — the template having more PropertyTypes than WidgetProperties — is not the defect. That asymmetry is intentional (system properties
Label/Visibility/Editabilitydeliberately have no value entry, per the comment inmodelsdk/widgets/generate.go), and 13 other shipped templates share it while working fine. The actual defect is the metadata vintage mismatch above.Fix
Mutator.ReplaceWidgetnow grafts the stored (old) widget's per-property display metadata —Caption,Category,Description— onto the replacement's freshly generatedTypeblock, so the rebuilt widget stays consistent with the stored model rather than with the toolchain's template:/markers/latitude), not flat key, so distinct nested object types that reuse a key keep independent metadata.WidgetIdmatches the replaced widget's — including pluggable widgets nested inside container replacements.$IDs andValueTypes are never copied, so the replacement'sObject↔Typecross-references (freshly generated IDs) stay intact.This is deliberately scoped to REPLACE, where "match the stored model" is unambiguous; the wider template/schema question stays with #529.
Verification
mdl/backend/pagemutator(same-widget graft, different-WidgetId untouched, non-pluggable old widget, nested object types, duplicate keys scoped by path, combobox nested in container replacement).go test ./...passes;make lint-goclean.docker check→ 1 error (CE0463).Caption/Categoryvalues are preserved byte-for-byte in the unit.where [Name != '']XPath datasource constraint → 0 errors, constraint present in the unit.