fix(alter-page): refuse widgets at a DataGrid2 column target, see into a customContent cell - #195
Merged
Merged
Conversation
…Content cell Two defects reported as mendixlabs#935, both verified on Mendix 10.24.20.105674 (the reported version) and 11.13.0. **1. A dotted column target still corrupted the page (the crash).** mendixlabs#891 fixed the BARE form — `insert after NextRunAt { … }` — by refusing it and pointing authors at `grid.NextRunAt`. That form skips the guard entirely, because the target is legitimate. What is wrong is the pairing: the executor routes an all-`column` body to InsertColumns/ReplaceColumn, and anything else fell through to the generic widget path and was serialized into the grid's COLUMN list. So the fix for mendixlabs#891 named the route to the same unloadable document: System.InvalidCastException: Unable to cast object of type '…LayoutWidgets.DivContainers.DivContainer' to type '…CustomWidgets.WidgetObject' mx check aborts on load, before reaching a single check. Refusing at the pairing covers INSERT (before/after/into) and REPLACE at once. The column is resolved first, so a mistyped name still reports not-found with the available names rather than the refusal. Measured: "Altered page" then a load abort, before. Refused, and the project still checks at 0 errors, after. **2. A widget inside a customContent cell bound nothing.** The entity-context walk descended into a pluggable widget's own widget properties but not into an object-list ITEM's — a DataGrid2 column keeps its cell widgets one level deeper, at Objects[].Properties[content].Value .Widgets. That is the descent findInWidgetChildren gained in mendixlabs#834; this second walk never learned it, so ALTER PAGE could FIND those widgets (and mendixlabs#834's fix made that the recommended way to edit a cell) while building their bindings with an empty entity context. An association-navigating ContentParams path then could not resolve into AttributeRef + EntityRef steps and was stored as the attribute NAME: CE1613 at build time, and a describe that silently dropped the first hop. CREATE PAGE got the identical page right, which is what made this read as a storage bug rather than a context bug. The walk also never read a pluggable widget's datasource at all, so the grid's own entity was invisible even one level up. Both readers now share entityFromEntityRef, which also gives the pluggable one the IndirectEntityRef (association) case the plain one already had. The descent is keyed on the BSON shape, not on the "columns" property key, so Accordion groups and PopupMenu items are covered by the same code. Measured: CE1613 before, 0 errors after, with the two-hop path round-tripping through describe. Note on the controls: reverting fix 1 makes its unit test nil-deref in the fixture rather than reproduce the symptom, so the honest control there is the CLI plus mx check, run against a real 10.24 project. Fix 2's five tests do fail with the reported "" before the fix, including a false-positive control (a nearer DataView must still shadow the grid, and a widget outside every bound container must still report no entity). Repros: mdl-examples/bug-tests/935-alter-page-widgets-at-column-target.mdl and 935-customcontent-column-entity-context.mdl. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018hifgRSawfaRWXS44YKtSJ
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.
Fixes the two defects reported as mendixlabs#935. Verified on Mendix 10.24.20.105674 (the reported version) and 11.13.0.
1. A dotted column target still corrupted the page (the crash)
mendixlabs#891 fixed the bare form —
insert after NextRunAt { … }— by refusing it and pointing authors atgrid.NextRunAt. That form skips the guard entirely, because the target is legitimate. What is wrong is the pairing: the executor routes an all-columnbody toInsertColumns/ReplaceColumn, and anything else fell through to the generic widget path and was serialized into the grid's column list. So the fix for mendixlabs#891 named the route to the same unloadable document:mx checkaborts on load, before reaching a single check. Refusing at the pairing covers INSERT (before/after/into) and REPLACE at once. The column is resolved first, so a mistyped name still reports not-found with the available names rather than the refusal.Measured on 10.24:
Altered pagethen a load abort, before. Refused, and the project still checks at 0 errors, after.2. A widget inside a customContent cell bound nothing
The entity-context walk descended into a pluggable widget's own widget properties but not into an object-list item's — a DataGrid2 column keeps its cell widgets one level deeper, at
Objects[].Properties[content].Value.Widgets. That is the descentfindInWidgetChildrengained in mendixlabs#834; this second walk never learned it.That is what makes it bite: mendixlabs#834 made those widgets addressable, so targeting the container by its own name is the recommended way to edit a cell — and it built every binding with an empty entity context. An association-navigating
ContentParamspath then could not resolve intoAttributeRef+EntityRefsteps and was stored as the attribute name:CREATE PAGEgot the identical page right, which is what made this read as a storage bug rather than a context bug.The walk also never read a pluggable widget's datasource at all, so the grid's own entity was invisible even one level up. Both readers now share
entityFromEntityRef, which also gives the pluggable one theIndirectEntityRef(association) case the plain one already had.The descent is keyed on the BSON shape, not on the
columnsproperty key, so Accordion groups and PopupMenu items are covered by the same code rather than tying the walk to one widget.Measured on 10.24: CE1613 before, 0 errors after, with the two-hop path round-tripping through
describe.On the issue's repro
The steps as written do not reproduce — the crash needs a non-
columnbody. The bare-name variant does crash on a build from the reported nightly (2026-07-20) and is refused today, so if that is what was actually run, mendixlabs#891 had already fixed it. Both live defects above are reproduced from a clean project and fixed here.Controls
""before the fix, including a false-positive control: a nearer DataView must still shadow the grid, and a widget outside every bound container must still report no entity.mx checkagainst a real 10.24 project, which is what was measured.mdl-examples/doctype-tests/33-alter-page-examples.mdluses dotted targets throughout withcolumn …bodies and is unaffected (re-run against a real project).Changes
mdl/backend/pagemutator/mutator.go—refuseWidgetsAtColumnTargetwired intoInsertWidget/ReplaceWidget; object-list descent infindEntityContextInChildren; newwidgetOwnEntityand sharedentityFromEntityRefmdl/backend/pagemutator/mutator_entity_context_test.go(new) — five tests for the entity walkmdl/backend/pagemutator/mutator_column_addressing_test.go— three tests for the new guard, driven through the exported methods so deleting a call site failsmdl-examples/bug-tests/935-alter-page-widgets-at-column-target.mdl,935-customcontent-column-entity-context.mdl(new, the second re-runnable).claude/skills/fix-issue.md— symptom row appendedgo test ./...,make lint-goandmake check-mdlare green.🤖 Generated with Claude Code
https://claude.ai/code/session_018hifgRSawfaRWXS44YKtSJ
Generated by Claude Code