Skip to content

fix: names Mendix rejects pass check — inherited member names (CE0069), reserved parameter names (CE7247) (#1645, #1651) - #1740

Merged
ako merged 3 commits into
mainfrom
fix/1645-reserved-member-names
Oct 27, 2026
Merged

ako merged 3 commits into
mainfrom
fix/1645-reserved-member-names

Conversation

@ako

@ako ako commented Oct 26, 2026

Copy link
Copy Markdown
Owner

Closes #1645. Closes #1651 (mirror of mendixlabs#1642).

A name Mendix rejects passed check and exec, and only the build reported it. One commit per issue (plus one keeping CLAUDE.md within its byte budget).

#1645 — a member reusing a name on its generalization chain (CE0069)

Measured (mx 11.13.0, blank app, 21 cases). CE0069 for: attribute vs attribute, association vs association, attribute vs association both ways; a name two generalization levels up; System ancestors' members (System.User.Name, System.UserRoles, System.FileDocument.Size); downward — adding to a generalization a name its specialization already has; renaming an attribute or association into such a name; an entity's own attribute and own association sharing a name. An association's name belongs to its FROM entity, and under owner Both (reference and reference set) to the TO entity as well. Clean: names differing only in case (the comparison is exact), two siblings with the same name, an unrelated entity, an attribute on the TO end of an owner-Default association.

Cause: nothing checked a name against the chain. The only CE0069 guard (dropInheritedTargets, cmd_entities_bulk.go) looked inside the bulk ALTER ENTITIES target set; the single-statement paths (create entity, alter entity add/rename attribute, create association, rename association) compared only the entity's own attributes or the module's association names.

Fix: one verdict, memberNameClash (new member_name_clash.go), over a model of each entity's generalization and attributes plus each association's ends, walking self, ancestors (System included) and descendants.

  • exec: each handler judges against the project before writing — create entity, alter entity add/rename attribute, create association, alter association set owner both, rename association; bulk ALTER ENTITIES judges every target before its first write.
  • check -p: the reference pass replays the script in statement order over the project (otherwise a drop-then-re-add would be falsely refused, and a parent created after its child missed). check without a project: the same replay over the System module from modelsdk/meta, reported as MDL-MEMBER01.
  • Only clashes the statement introduces are reported, so an unchanged create or modify re-run is not refused. The message names the member holding the name, its declaring entity, CE0069 and a fix.

Verified: PedApp check/exec agreement tests for every shape plus controls (member_name_clash_pedapp_test.go) and a project-free test. Reverted wiring: all nine tests fail, controls pass; reverting only the check pass fails check's half. A false positive found in final review (dropping an entity did not drop its associations in the replay) has a regression test. Real app: baseline 16× CE0069; fixed check and exec refuse those 16, the 5 clean cases are written, mx check 0 errors. Exec cost ≈ 8 ms per entity/association statement (137 calls added ≈ 1.1 s to the 23 s domain-model doctype exec).

#1651 — a page parameter named Context (CE7247)

Measured (~120 names × six contexts, mx 11.13.0): page, snippet, Java action and JavaScript action parameters follow exactly the existing types.PlatformReservedWords list — case-insensitive, quoted refused too. Every listed name gave CE7247; unlisted names were clean (incl. currentObject, latestError, latestHttpResponse, String, System, User, List, record). The exception: Object is CE7247 there and on an attribute, enumeration value and entity, but was missing from the list. The list does not apply to microflow/nanoflow parameters ($Context, $Type, $Class build clean) or page variables.

Cause: the list was applied only to attribute names (MDL021) and enumeration values (MDL010). Fix: new rule MDL-PARAM01 (validate_reserved_parameter_names.go) for create page/snippet, alter page/snippet add parameters, create java action, create javascript action — in ValidateProgram (check and exec's preflight) and in the five exec handlers, so --no-check cannot write it either; the suggested rename is the parameter's entity name. object added to the shared list (MDL021 and MDL010 now catch it too).

Verified: unit tests per context, with controls (non-reserved name, a system-variable name, microflow/nanoflow parameters); a PedApp check/exec agreement test; reverted wiring fails all. Real app: the 61 probe scripts baseline mx check flagged with CE7247 (62 parameters) plus the reporter's page are refused; the other 109 are written at 0 errors; the reporter's workaround $LaneContext is accepted.

All

  • No regressions: all 81 non-.fail doctype scripts give identical output on main and fixed, with and without -p; domain-model doctype scripts exec identically; 650 related bug-test and skill scripts give identical check results.
  • Full go test ./... (incl. the CLAUDE.md budget test), go vet, gofmt; CI's doc checks pass locally. Bug-tests member-name-1645-inherited-attribute.fail.mdl, member-name-1645-inherited-association.fail.mdl, page-params-1651-reserved-context.fail.mdl; findings recorded; generate-domain-model and create-page skills, docs-site create-entity / create-page; CLAUDE.md's reserved-names note (Object, MDL-PARAM01, the list's location in mdl/types/reserved_words.go).
  • Not verified: -tags integration doctype mx-check runs.

Noticed, not fixed

  1. Microflow/nanoflow parameters and variables named with system-variable names pass check and exec and mxbuild rejects them: CE0110 for currentObject, latestError (both flow kinds), latestHttpResponse, latestSoapFault, currentSession, currentDeviceType as microflow parameters/variables; CE0039 for a microflow variable CurrentUser and nanoflow variables CurrentUser, currentDeviceType, currentSession, latestHttpResponse.
  2. Entity names are not checked against the reserved list (Object measured CE7247).
  3. reservedEntityAttrNames (cmd_contract.go, OData import auto-rename) is a separate, narrower list without object and the Java keywords (not measured).
  4. From reading only: in execCreateAssociation, a create or modify for an association that exists in the other list (same-module vs cross-module) falls through and creates a second association of the same name.

🤖 Generated with Claude Code

ako and others added 3 commits October 26, 2026 23:09
… and exec (#1645)

A specialization's attribute or association named like a member it
inherits, a generalization gaining a member a specialization already has,
a rename into such a name, and an entity's own attribute and association
of one name all passed `check -p` and exec; mxbuild rejected the model
with CE0069 "Duplicate member name".

Cause: nothing decided "this entity already has a member of that name"
along the chain. The only CE0069 guard was dropInheritedTargets inside
bulk ALTER ENTITIES, which looks only within the target set; the single
statements checked the entity's own attributes or the module's
association names.

Fix: one verdict, memberNameClash, over a member world (each entity's
generalization and attributes, each association's ends):
- exec calls it against the project before writing, in create entity,
  alter entity add/rename attribute, create association, alter
  association set owner both and rename association; bulk ALTER ENTITIES
  judges every target before its first write;
- check -p replays the script over the project's members in statement
  order (so a drop-then-re-add passes and a one-script parent/child pair
  is caught), judging each statement with the same verdict;
- `check` without a project runs the same replay over the System module
  from modelsdk/meta (MDL-MEMBER01), so the issue's scripts fail even
  there.
The message names the member already holding the name, its declaring
entity, and the CE0069 it prevents.

Measured on mx 11.13.0 (17 shapes in one app, then 4 more): CE0069 for
attribute/attribute, association/association, both mixed directions, two
levels up, System.User.Name, System.UserRoles, System.FileDocument.Size,
the downward direction, attribute and association renames, and an
entity's own attribute vs association; an association is a member of its
TO entity only under owner Both. Clean: names differing only in case,
siblings, an unrelated entity, an owner-Default TO-side attribute.

Verification: PedApp check/exec agreement tests for every shape plus
controls, and a project-free test; reverting the wiring fails all nine
(controls still pass), reverting only the check pass fails check's half.
Real 11.13 app: baseline wrote 16 CE0069 models; fixed, check and exec
refuse those 16, the 5 clean shapes are written, mx check 0 errors.
Doctype sweep (81 scripts, check with and without -p) and 238
domain-model bug-test/skill scripts: identical to main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mirror of mendixlabs#1642. A page parameter named `Context` passed
check and exec, and mx check reported CE7247 "The name 'Context' is a
reserved word." — after the page and its callers had been written.

Cause: the platform reserved-word list (types.PlatformReservedWords) was
applied to attribute names (MDL021) and enumeration values (MDL010) only;
nothing looked at parameter names. The list also lacked `object`.

Fix: MDL-PARAM01 checks the parameters of create page / create snippet /
alter page|snippet add parameters / create java action / create
javascript action against that same list (case-insensitive, quotes
stripped), in ValidateProgram (check, exec's pre-flight) and in the five
exec handlers, so --no-check cannot write it either. The message names
the CE7247 and suggests the parameter's entity as a name ($Sale). `object`
is added to the shared list, so MDL021/MDL010 cover it too.

Measured on mx 11.13.0, ~120 names over six contexts: pages, snippets,
Java and JavaScript actions take exactly the attribute list — every
listed name tried is CE7247 in any case and quoted, every unlisted one
clean (incl. currentObject, latestError, String, System, User, List,
record) — except `Object`, CE7247 there and on an attribute, an
enumeration value and an entity. Microflow and nanoflow parameters and
page variables do not use this list ($Context, $Type, $Class build
clean); flows refuse the system-variable names instead (CE0110/CE0039),
which this does not cover.

Verification: unit tests per context plus controls (another name, a
system-variable name, microflow/nanoflow parameters), a PedApp
check/exec agreement test; reverting the wiring fails all of them,
reverting only the page handler fails exec's half. Real 11.13 app: the 61
probe scripts baseline mx check reported CE7247 for (62 parameters) and
the reporter's page are refused by check and exec, the other 109 are
written, mx check 0 errors. Doctype sweep (81 scripts,
check with and without -p) and 412 related bug-test scripts: identical
to main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reserved-names note grew CLAUDE.md past the budget
TestRepoClaudeMDStaysWithinItsContextBudget enforces (28224 bytes). Keep the
facts it carries — Object is reserved, the list binds page/snippet/Java/
JavaScript action parameters (MDL-PARAM01), and where the list lives — in
fewer words; the microflow-parameter nuance is in the skills and the finding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ako
ako merged commit b81d7d8 into main Oct 27, 2026
33 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

1 participant