From 9064b4c035712eefbd32160805745604b8200ce5 Mon Sep 17 00:00:00 2001 From: Andrej Koelewijn Date: Sat, 23 May 2026 10:28:37 +0000 Subject: [PATCH 1/2] fix #590: rewrite Level 9.1 call-external-action to use TripPin schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original Level 9.1 created a microflow `OdTest.ACT_CallExternalAction` that called `OdTest.SalesforceAPI.GetAccounts(...)` and `OdTest.SalesforceAPI.NotifyUpdate(...)`. SalesforceAPI's MetadataUrl is a placeholder that doesn't return $metadata, so the ConsumedODataService BSON is written with an empty `Metadata` cache. Studio Pro's project checker then resolves the Name fields against an empty schema, gets null, and the checker aborts with a NullReferenceException in `Mendix.Modeler.Integration.CallExternalAction.get_SchemaAction()` → `ExternalActionParameterMapping.get_SchemaParameter()`. The crash blocks all in-IDE error reporting, not just for this microflow. Move the microflow definition to a new Level 10.4.1, right after the TripPin client is created (Level 10.1) and its $metadata is actually cached. Use unbound TripPin entries `GetNearestAirport` (Function with lat/lon parameters and a Trippin.Airport return) and `ResetDataSource` (parameterless Action) so both the parameter-mapping and the `on error continue` variants are still demonstrated. The microflow stays in `OdTest` so `show external actions in OdTest` (Level 9.2) still returns a row. The existing drop in Level 8.8a already runs before Level 8.8c (TripPin client drop), so cleanup order is correct. Issue #590 separately documents the upstream Studio Pro robustness gap (`SchemaAction` should null-check instead of NREing) so it can be escalated to Mendix support. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../doctype-tests/10-odata-examples.mdl | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/mdl-examples/doctype-tests/10-odata-examples.mdl b/mdl-examples/doctype-tests/10-odata-examples.mdl index edb0ed3f1..af09e78ca 100644 --- a/mdl-examples/doctype-tests/10-odata-examples.mdl +++ b/mdl-examples/doctype-tests/10-odata-examples.mdl @@ -378,16 +378,15 @@ revoke access on odata service OdTest.CustomerAPI from OdTest.user; -- LEVEL 9: EXTERNAL ACTION CALLS IN MICROFLOWS -- ############################################################################ -/** - * Level 9.1: Call an external action with parameters and result variable - */ -create microflow OdTest.ACT_CallExternalAction() returns boolean -begin - $Result = call external action OdTest.SalesforceAPI.GetAccounts(status = 'active', Region = $SelectedRegion); - call external action OdTest.SalesforceAPI.NotifyUpdate(AccountId = $AccountId) on error continue; - return true; -end; -/ +-- Level 9.1: Call an external action — see Level 10.4.1 below. +-- +-- The microflow is created after Level 10.1 because Studio Pro resolves +-- `call external action` Name fields against the cached $metadata schema of +-- the ConsumedODataService. SalesforceAPI's MetadataUrl is a placeholder +-- that doesn't actually return $metadata, so its cache is empty and any +-- action call against it would crash Studio Pro's project checker with a +-- NullReferenceException in CallExternalAction.SchemaAction (see mxcli#590). +-- TripPin has reachable metadata, so its actions resolve correctly. /** * Level 9.2: Show external actions discovered from microflow usage @@ -462,14 +461,31 @@ create or modify external entities from TripPinClient."TripPinApiClient" into TripPinClient; / +/** + * Level 10.4.1: Demonstrate `call external action` against TripPin schema + * actions. Both ResetDataSource (no parameters) and GetNearestAirport + * (parameterised with a return variable) are unbound entries in TripPin's + * cached $metadata, so Studio Pro's project checker resolves SchemaAction + * correctly. The microflow lives in OdTest to keep `show external actions + * in OdTest` (Level 9.2) returning a row, but references the TripPin client. + */ +create microflow OdTest.ACT_CallExternalAction() returns boolean +begin + $Airport = call external action TripPinClient."TripPinApiClient".GetNearestAirport(lat = 47.6062, lon = -122.3321); + call external action TripPinClient."TripPinApiClient".ResetDataSource() on error continue; + return true; +end; +/ + -- ############################################################################ -- LEVEL 8.8: DROP (cleanup) -- ############################################################################ /** - * Level 8.8a: Drop objects that reference SalesforceAPI before dropping the client. - * OdTest.ACT_CallExternalAction calls SalesforceAPI actions; OdTest.RemoteAccount - * is an external entity backed by SalesforceAPI — both must be removed first. + * Level 8.8a: Drop objects that reference OData clients before dropping the + * clients themselves. OdTest.ACT_CallExternalAction (created in Level 10.4.1) + * calls TripPin actions, and OdTest.RemoteAccount is an external entity + * backed by SalesforceAPI — both must be removed first. */ drop microflow OdTest.ACT_CallExternalAction; / From 2f2465a4cea6df68b22435e2e79c21838444fd0a Mon Sep 17 00:00:00 2001 From: Andrej Koelewijn Date: Sat, 23 May 2026 12:46:26 +0000 Subject: [PATCH 2/2] fix #594: re-state RemoteName in Level 8.6c to avoid Studio Pro Integration pane NRE `create or modify external entity` overwrites `RemoteEntityName` (BSON field `RemoteName`) with the empty string when the `RemoteName` property is omitted from the statement (see mxcli#594). Level 8.6c was relying on preservation of the value set by 8.6a/8.6b, but the resulting BSON ended up with `RemoteName: ""`. Studio Pro's Integration Pane visualiser then NREs in `ODataRemoteEntitySource.get_RemoteId()` with `ArgumentNullException("EntityTypeName")` because the C# property aliases the BSON `RemoteName` field. Repeat `RemoteName: 'Account'` in 8.6c. The underlying executor bug is tracked separately in #594 and will be fixed in its own PR; this commit keeps the example file usable today. Co-Authored-By: Claude Opus 4.7 (1M context) --- mdl-examples/doctype-tests/10-odata-examples.mdl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mdl-examples/doctype-tests/10-odata-examples.mdl b/mdl-examples/doctype-tests/10-odata-examples.mdl index af09e78ca..2ba4db7bf 100644 --- a/mdl-examples/doctype-tests/10-odata-examples.mdl +++ b/mdl-examples/doctype-tests/10-odata-examples.mdl @@ -332,11 +332,19 @@ from odata client OdTest.SalesforceAPI * Level 8.6c: Create external entity with AllowCreateChangeLocally flag * Enables local creation/changes for the entity, mirroring Studio Pro's * "Allow creating and changing locally" checkbox on external entities. + * + * RemoteName must be repeated here because `create or modify external entity` + * currently overwrites omitted properties with empty strings rather than + * preserving the existing value. Without `RemoteName: 'Account'`, the BSON + * ends up with `"RemoteName": ""`, which Studio Pro's Integration Pane + * visualiser cannot render (NRE in ODataRemoteEntitySource.RemoteId, + * mxcli#594). */ create or modify external entity OdTest.RemoteAccount from odata client OdTest.SalesforceAPI ( EntitySet: 'Accounts', + RemoteName: 'Account', Countable: Yes, Creatable: Yes, Deletable: No,