Skip to content

fix: silent-property-drop cluster — container RenderMode, Calendar expressions, column Filterable - #1498

Merged
ako merged 4 commits into
mainfrom
claude/silent-property-drop-issues-55o66g
Oct 20, 2026
Merged

ako merged 4 commits into
mainfrom
claude/silent-property-drop-issues-55o66g

Conversation

@ako

@ako ako commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Works the silent-property-drop row of the triage board (#1357). Six issues: three fixed here, three already fixed on main.

Closes #1487
Closes #1483
Closes #1230

Changes

One commit per issue, plus a docs commit.

#1487 — container (RenderMode: 'Main') "isn't stored" (mendixlabs#1582)

Reported: describe layout printed container ctnMain (Class: 'app-main') {, and alter layout … set refused the property.

  • The write was always correct. bson dump shows RenderMode: "Main" on the stored Forms$DivContainer.
  • describe never read it. That made it look dropped, and a describe → exec round trip did drop it. Now describe prints RenderMode: Main, leaving out the default Div.
  • alter page|layout … set (RenderMode: …) on a container now writes it. Before, it was refused with not a property of this built-in widget.
  • create wrote any string as-is into the enum ('main', 'Banner'). Values are now matched case-insensitively against the generated enum (Div … Address), and an unknown member is refused. The hand-written sdk/pages enum had drifted (Div, Form).

#1483 — Calendar editable / showEventDate fail mx check with CE0642 (mendixlabs#1578)

Reported: [CE0642] "Property 'Editable' is required." and "Property 'Show event date range' is required.". Both are type="expression" defaultValue="true". Four separate gaps:

  1. modelsdk/widgets/augment.go: the template generated from the .mpk wrote an expression's defaultValue as an empty expression. It now writes the default, which on its own makes every Calendar page build.
  2. GenerateDefJSON: a top-level expression property had no mapping, so it was "known but not persisted" and drew a false MDL-WIDGET06. It is now mapped by its own key. Widget definition generator bumped to v19.
  3. editable: is also the generic widget-level editability, which the Calendar's package does not declare. The widget's own editable was therefore unreachable in every spelling. When the package declares no Editability system property, the generator now routes editable: (all value shapes) to the widget's own property, and check (MDL-WIDGET41) and build both read that decision. When the package does declare it, editable: keeps its widget-level meaning.
  4. describe had no branch for an Expression value. It now prints stored expressions.

An unset expression mapping keeps the template default instead of writing "" over it.

#1230 — column (Attribute: Name, Filterable: true) (mendixlabs#177)

  • Already refused on main, so it is no longer a silent drop. What was left was the message: with a project it listed the column's properties, and without one it suggested did you mean FilterType?, which a column doesn't have.
  • New message: a key starting with an item's widgets-slot key now names the slot, the body form, and the widget types it takes: — `filter` is a slot for child widgets, not a property: put the widget in the column's braces, e.g. `column (…) { textfilter w1 (…) }` (it takes textfilter, numberfilter, datefilter, dropdownfilter).

Already fixed on main, no change

Docs

Two short paragraphs on docs-wiki/bug-patterns/silent-property-drop.md: check the stored document before blaming the write path, and a builtin MDL key can shadow a widget's own property of the same name.

Validation

  • Tests written first. Each one fails with the reported symptom when its fix is reverted:
  • Run against real mxbuild (Mendix 11.13.0) on a mxcli new app with Calendar 245304 v2.6.1 from the Marketplace:
    • main's binary: CE0642 × 2.
    • This branch: The app contains: 0 errors. with neither property set, with both 'true', and with editable: false, showEventDate: 'false'. A describe → exec round trip reports Unchanged page.
    • The column-filter form the new message suggests builds with 0 errors.
  • Two existing generator tests updated (TestGenerateDefJSON_SkipsComplexTypes, TestGenerateDefJSON_KnownPropertiesUnmapped). They asserted that expression properties stay unmapped, the behaviour this PR changes. The unmapped example is now an icon property.
  • Regression scripts: mdl-examples/bug-tests/1582-container-rendermode.mdl, 1578-calendar-expression-properties.mdl (needs the Calendar package), 177-datagrid-column-filter-slot.mdl.
  • One finding file per fix under .claude/skills/fix-issue/findings/mdl-executor/.
  • make build && make test && make lint, make check-mdl, make check-findings and make check-wiki-pages pass.

Generated by Claude Code

A layout or page container's RenderMode was stored but describe never
printed it, so it read as dropped and a describe -> exec round trip did
drop it. alter set routed RenderMode only for dynamic texts and refused
it on a container, and create wrote any string verbatim into the enum.

Fixes mendixlabs#1582 (#1487).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SPETbWEhRQ85EX4gckfCxU
The Marketplace Calendar's required editable and showEventDate
expressions (defaultValue="true") failed mx check with CE0642: the
mpk-generated template wrote them empty, the def generator gave a
top-level expression no mapping, editable: only reached the widget-level
editability (which the Calendar does not declare), and describe printed
neither.

The template now writes an expression's declared default, the generator
maps every top-level expression by its own key (v19), editable: routes
to the widget's own property when the package declares no Editability,
and describe prints stored expressions.

Fixes mendixlabs#1578 (#1483).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SPETbWEhRQ85EX4gckfCxU
A Data grid 2 column has no Filterable property: its filter is the
column's filter slot, written as a filter widget in its braces. check
already refused the key, but the hint listed the column's properties
(with a project) or suggested FilterType (without one). A key that
starts with an item's widgets-slot key now names the slot, the body
form, and the widget types it routes.

Fixes the remaining part of mendixlabs#177 (#1230).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SPETbWEhRQ85EX4gckfCxU
Read the store before the writer (a container's RenderMode was stored;
only describe lacked it), and a builtin key can shadow a pluggable
widget's own property of the same name (the Calendar's editable).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SPETbWEhRQ85EX4gckfCxU
@ako
ako merged commit f82bb02 into main Oct 20, 2026
31 checks passed
ako pushed a commit that referenced this pull request Oct 20, 2026
main is red. The merge of #1497, which removed
go.mongodb.org/mongo-driver v1 from go.mod, landed just after #1498
added mdl/backend/pagemutator/container_rendermode_test.go — a file
written against v1. The package now fails to compile at all:

  container_rendermode_test.go:8:2: no required module provides package
  go.mongodb.org/mongo-driver/bson
  FAIL github.com/mendixlabs/mxcli/mdl/backend/pagemutator [setup failed]

and TestNoV1DriverImports names the file, which is what it is for.

Neither PR is at fault. #1498 was authored and tested against a main
that still required v1, the two touched different files so nothing
conflicted, and each was green on its own base. The combination is what
breaks.

The file uses bson.D only, so this is the import path and nothing else:
v2 nests bson.D inside bson.D exactly as v1 nested primitive.D, so its
assertions are already correct and it needs no modelsdk/bsoncompat
helper.

Checked the whole tree rather than just the file CI named, since `go
test` stops at the first [setup failed] package and a second offender
would only surface on the next run: this is the only one.

Verified: go build ./... clean, go vet clean, gofmt clean, 106 test
packages pass with 0 failures, the two packages that failed in CI
(mdl/backend/pagemutator and modelsdk/bsoncompat) both pass, and `go mod
tidy` exits 0 leaving go.mod and go.sum unchanged — so v1 stays out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rer1mzP69XxbXKxQqheipM
ako added a commit that referenced this pull request Oct 20, 2026
fix(test): point container_rendermode_test at the v2 BSON driver

Unbreaks main. #1497 removed go.mongodb.org/mongo-driver v1 from go.mod
just after #1498 added a test file written against it, so
mdl/backend/pagemutator stopped compiling and TestNoV1DriverImports
named the file. Neither PR is at fault: each was green on its own base
and the two touched different files, so nothing conflicted — only the
combination breaks.

The file uses bson.D only, so this is the import path alone; v2 nests
bson.D inside bson.D exactly as v1 nested primitive.D, needing no
modelsdk/bsoncompat helper. Whole tree checked, not just the file CI
named: this is the only one.
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