Skip to content

calculated by on an attribute is silently discarded on write — stored as DomainModels$StoredValue with no calculation link, on both CREATE and ALTER paths #917

Description

@MendixMau

Environment

  • mxcli v0.17.0 (2026-08-10T05:12:17Z)
  • Retested on mxcli v0.18.0 (2026-08-14T20:29:13Z, official darwin-arm64 release binary): still reproduces, unchanged.
  • Model format: MPR v2 split-tree (mprcontents/), project at Mendix 11.12.0
  • mxbuild/Studio Pro available: 11.12.0, 11.12.1, 11.13.0
  • macOS 26.6, arm64

Summary

calculated by Module.Microflow is accepted by mxcli check, by check --references, and by
mxcli exec (which reports Added attribute / Created entity), but the calculation binding
is never written to the model.
The attribute is stored as an ordinary
DomainModels$StoredValue and the calculation microflow is not referenced anywhere in the
domain-model unit.

This is a write-path defect, not a read-back defect — confirmed by decoding the stored BSON, not
by DESCRIBE.

Steps to reproduce

Against any project. MyFirstModule below is the default module of a stock mxcli-scaffolded app.

create persistent entity "MyFirstModule"."ZZTEST_Foo" (
  "Name": String(50)
);

create microflow "MyFirstModule"."GET_ZZTEST_WithParam" ($Foo: "MyFirstModule"."ZZTEST_Foo")
returns integer as $result
begin
  return 42;
end

alter entity "MyFirstModule"."ZZTEST_Foo"
  add attribute "AnswerA": Integer calculated by "MyFirstModule"."GET_ZZTEST_WithParam";
mxcli check script.mdl                          → ✓ Syntax OK (3 statements)
mxcli check script.mdl -p App.mpr --references  → ✓ All references valid
mxcli exec  script.mdl -p App.mpr               → Created entity / Created microflow / Added attribute 'AnswerA'

The microflow deliberately has the entity-typed parameter Mendix requires of a calculation
microflow, and returns the attribute's type. It satisfies the documented contract.

Expected

The attribute is stored with a calculated value type referencing
MyFirstModule.GET_ZZTEST_WithParam.

Actual

1. DESCRIBE renders it as a plain attribute — the clause is gone:

create or modify persistent entity MyFirstModule.ZZTEST_Foo (
  Name: String(50),
  AnswerA: Integer
);

2. The stored BSON confirms it is genuinely absent, not merely unrendered. Decoding the
domain-model .mxunit written by the exec, the complete set of DomainModels$ type tokens is:

DomainModels$Annotation          DomainModels$Attribute
DomainModels$DomainModel         DomainModels$EntityImpl
DomainModels$IntegerAttributeType DomainModels$NoGeneralization
DomainModels$StoredValue         DomainModels$StringAttributeType

DomainModels$StoredValue is present. There is no calculated value type, and a search of the
unit for GET_ZZTEST_WithParam or any calculat* token returns nothing. The microflow name
appears only in its own microflow unit.

3. SHOW CALLERS OF MyFirstModule.GET_ZZTEST_WithParam(no callers found), consistent
with no link existing at model level.

Trigger boundary — both paths fail

Form check exec reports stored value type
alter entity … add attribute "AnswerA": Integer calculated by … 0 errors Added attribute 'AnswerA' StoredValue
create persistent entity … ( "AnswerC": Integer calculated by … ) — the form in mxcli's own docs 0 errors Created entity StoredValue

Both were run in the same session against the same project. There is no form that works, so
there is no workaround beyond abandoning calculated attributes and computing the value actively.

Additional finding — no signature validation either

A calculation microflow with no parameter at all (GET_ZZTEST_NoParam()) is equally accepted
by check --references and exec. Mendix requires the microflow to take a parameter of the
entity type, so this form could never work even if the binding were written.

This is arguably a second, separate defect (different fix location — validator vs. writer), but
it is currently masked: the clause is dropped for every microflow regardless of signature, so
signature validation is unreachable. Noting it here rather than filing separately, because fixing
the writer will expose it.

Severity

Silent. Every signal a user has says the wiring succeeded: check passes, exec prints
Added attribute, and native mx check reports no error because a plain stored attribute is
perfectly valid. The failure only appears at runtime as an attribute that is always empty —
indistinguishable from a stored attribute nobody assigned.

Real-project impact observed on three attributes across two modules before the cause was found;
each read as empty on every retrieve, and the diagnosis took a live in-browser mx.data.get
round-trip because no static check disagrees.

Scoped to mxcli v0.17.0 with a Mendix 11.12.0 model. Original observations were on 11.13.0, so
the defect is not specific to one Mendix version, but I have BSON-verified it only on 11.12.0.

Note on a misleading diagnostic

CATALOG.ATTRIBUTES.IsCalculated cannot be used to detect this. It read 0 for all 355
attributes of a real project, including ones independently proven broken — the column appears
never to be populated, so it cannot distinguish wired from unwired in either direction.

Suggested fix location

The attribute-writing path used by both create entity and alter entity … add attribute:
the parsed calculated by clause is reaching neither, and the attribute is constructed with a
default stored value type. Secondarily, check --references should reject a calculation
microflow whose signature cannot satisfy the binding (see "Additional finding").

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions