Skip to content

fix(mappings): an unauthored import range is All, not First - #192

Merged
ako merged 1 commit into
mainfrom
claude/bootstrap-prompt-smaller-37u3fu
Aug 19, 2026
Merged

fix(mappings): an unauthored import range is All, not First#192
ako merged 1 commit into
mainfrom
claude/bootstrap-prompt-smaller-37u3fu

Conversation

@ako

@ako ako commented Aug 19, 2026

Copy link
Copy Markdown
Owner

import from mapping M.IMM($json) — the bare form, with no range keyword — built a document the Mendix runtime refuses:

com.mendix.modules.microflowengine.MicroflowException: key not found: Path(QName(None,),None,)
  at RT.ACT_Boot (Import with mapping : 'Import from JSON')
Caused by: java.util.NoSuchElementException: key not found: Path(QName(None,),None,)
  at com.mendix.integration.importer.mapping.MappingCache.storeValueMappingElement(MappingCache.scala:73)
  at com.mendix.integration.importer.json.JsonImporter.importStream(JsonImporter.scala:24)

Reported as "import mapping documents fail at runtime — JSON path resolution is broken in mxcli's serialization." The mapping document turned out to be fine; the defect is in the activity.

Root cause

The Range and the result variable's cardinality are separate axes (mendixlabs#881). But an unauthored range set neither pointer, so ForceSingleOccurrence and ConstantRange.SingleObject both fell back to SingleObjecttrue for an object-rooted mapping. That is Studio Pro's First ("take one of a list"), which is a different activity.

Studio Pro writes both flags false for a plain single-object import and expresses "one object" solely through VariableType=ObjectType:

VariableType ForceSingleOccurrence ConstantRange.SingleObject
Studio Pro (single object) ObjectType false false
mxcli before this change ObjectType true true

all, first and limit/offset each set their pointers explicitly, so only the bare form was affected — the form the shipped examples use (06-rest-client-examples.mdl:1506, :1541). first is deliberately unchanged.

Why nothing caught it

The model is valid. mxcli check, mx check (0 errors) and mxbuild all pass — the document is well-formed, it just means something else. It fails only when the activity runs, and the repo had no runtime coverage of import mappings at all: every existing mapping test stopped at mx check. This is exactly the gap .claude/skills/verify-in-runtime.md exists for.

How it was located

A Studio Pro-authored app on the same Mendix version (11.13.0) with the same JSON snippet, run under mxcli run --local, then cross the variables:

Case Result
Studio Pro microflow → Studio Pro mapping imports
mxcli microflow → mxcli mapping throws
mxcli microflow → Studio Pro's mapping throws
mxcli mapping over Studio Pro's structure + entity throws
mxcli microflow, ... all vs bare, same mapping, same boot all imports, bare throws

The last row is the discriminator; the third is what ruled out the mapping document, the JSON structure and the entity. An "isolation" where both artifacts are mxcli's isolates nothing — two earlier conclusions were wrong for exactly that reason, including one that blamed the mapping document.

Four document-level differences vs Studio Pro were each applied and booted, individually and combined, and none fixed it: int32 vs int64 on 14 numerics, root MinOccurs 0 vs 1, missing MessageDefinition2, blanked OriginalValue. BSON key order (Studio Pro writes alphabetically) was also tested and eliminated. Those divergences are real but out of scope here.

Testing

  • Written test-first: TestImportRange_UnauthoredObjectRootedWritesAllNotFirst fails pre-fix with range SingleObject = true and ForceSingleOccurrence = <nil> — causation shown from both directions, since the runtime independently threw the reported exception.
  • Verified at runtime, not just at check time: with the fix, the bare form and all both import in the same boot.
  • TestImportRange_UnauthoredKeepsTheOldInference asserted the faulty fallback (RangeSingleObject == nil) and is updated. It passed only because it exercised the list-rooted case, where the fallback is false either way and therefore harmless — renamed to ...KeepsTheCardinalityInference, keeping the part that is still true.
  • go test ./... green, make check-mdl 352 PASS / 0 FAIL, gofmt clean.
  • Fixture: mdl-examples/bug-tests/import-mapping-single-object-runtime.mdl (bare form plus the all and first controls). Symptom row appended to fix-issue.md.

Follow-ups, not in this PR

  • The four divergences above are each real and still unfixed.
  • show references to <import mapping> reports none even when a microflow uses it.
  • No .test.mdl anywhere exercises import from mapping; adding one under mxcli test --local is what would have caught this.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Dp1syGhH8yr7Hve2wwjzqg


Generated by Claude Code

`import from mapping M.IMM($json)` — no range keyword — built a document the
Mendix runtime refuses:

    MicroflowException: key not found: Path(QName(None,),None,)
      at ...integration.importer.mapping.MappingCache.storeValueMappingElement

The model is valid, so nothing static caught it: mxcli check, mx check (0
errors) and mxbuild all pass. It fails only when the activity runs, and the
repo had no runtime coverage of import mappings — every existing test stopped
at mx check.

The Range and the result variable's cardinality are separate axes (mendixlabs#881), but
an unauthored range set neither pointer, so ForceSingleOccurrence and
ConstantRange.SingleObject both fell back to SingleObject — true for an
object-rooted mapping. That is Studio Pro's First ("take one of a list"), not a
single-object import. Studio Pro writes both flags false and expresses "one
object" solely through VariableType=ObjectType.

`all`, `first` and limit/offset each set the pointers explicitly, so only the
bare form was affected — the form the shipped examples use
(06-rest-client-examples.mdl:1506, :1541). `first` is unchanged.

Measured against a Studio Pro-authored app on 11.13.0: in one boot, over the
same mapping and the same JSON, `... all` imported and the bare form threw;
with the fix both import. The cross-test is what located it — an mxcli
microflow calling Studio Pro's own mapping fails too, which rules out the
mapping document, the JSON structure and the entity.

Also updates TestImportRange_UnauthoredKeepsTheOldInference, which asserted the
faulty fallback. It passed only because it exercised the list-rooted case,
where the fallback is false either way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dp1syGhH8yr7Hve2wwjzqg
@ako
ako merged commit d4998ac into main Aug 19, 2026
7 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

Development

Successfully merging this pull request may close these issues.

2 participants