Trellis Session Insight
mindfold-ai/Trellis
Reach into past AI conversation history through the trellis mem CLI.
Diagnose BSON serialization problems in the MPR file — missing properties, wrong storage names, widget definitions Studio Pro rejects.
$ npx skills add mendixlabs/mxcli --skill debug-bson -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mendixlabs/mxcli debug-bson --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/mendix/debug-bson .claude/skills/debug-bson && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "debug-bson" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/mendix/debug-bson into .claude/skills/debug-bson/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "debug-bson", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/mendix/debug-bsonType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mendixlabs/mxcli --skill debug-bson -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mendixlabs/mxcli debug-bson --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/mendix/debug-bson .agents/skills/debug-bson && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "debug-bson" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/mendix/debug-bson into .agents/skills/debug-bson/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "debug-bson", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mendixlabs/mxcli --skill debug-bson -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mendixlabs/mxcli debug-bson --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/mendix/debug-bson .cursor/skills/debug-bson && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "debug-bson" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/mendix/debug-bson into .cursor/skills/debug-bson/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "debug-bson", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mendixlabs/mxcli.git --path .claude/skills/mendix/debug-bson--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mendixlabs/mxcli --skill debug-bson -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mendixlabs/mxcli debug-bson --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/mendix/debug-bson .gemini/skills/debug-bson && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "debug-bson" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/mendix/debug-bson into .gemini/skills/debug-bson/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "debug-bson", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mendixlabs/mxcli debug-bsonInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mendixlabs/mxcli --skill debug-bson -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/mendix/debug-bson .github/skills/debug-bson && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "debug-bson" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/mendix/debug-bson into .github/skills/debug-bson/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "debug-bson", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mendixlabs/mxcli --skill debug-bson -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mendixlabs/mxcli debug-bson --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/mendix/debug-bson .opencode/skills/debug-bson && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "debug-bson" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/mendix/debug-bson into .opencode/skills/debug-bson/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "debug-bson", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
debug-bsonDiagnose BSON serialization problems in the MPR file — missing properties, wrong storage names, widget definitions Studio Pro rejects.
Debug Bson is an agent skill from mendixlabs/mxcli. Diagnose BSON serialization problems in the MPR file — missing properties, wrong storage names, widget definitions Studio Pro rejects. Use when something created through MDL does not appear correctly in Studio Pro, or when a CE error points at a document mxcli wrote.
Its SKILL.md is about 5.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Debugging. The repository describes itself as: Mendix cli tool, a headless way to work with Mendix projects. Enables Mendix projects for use with 3rd party agentic coding tools like Claude Code and Copilot. Includes a… The licence is Apache-2.0.
5 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit a924d11. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
jqgoFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Debug Bson loads about 5.2k tokens when it runs. Until then it costs about 70 tokens; SKILL.md has 1,154 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from mendixlabs/mxcli at commit a924d11, republished under its Apache-2.0 licence (© mendixlabs). 1,154 words, ~5,247 tokens.
.claude/skills/debug-bson/SKILL.md (or your agent's skills folder).This skill provides guidance for debugging BSON serialization issues when implementing or fixing Mendix SDK writers.
Use this skill when:
When the ModelSDK Go serializes objects to BSON, the output must exactly match what Mendix Studio Pro expects. Even small differences in:
caption vs CaptionTemplate)[2, items...] vs [3, items...])...can cause Studio Pro to ignore the data entirely.
Symptoms that indicate BSON serialization issues:
describe command shows correct data, but Studio Pro shows empty/defaultUse the mxcli bson dump command to extract and compare:
# Dump the SDK-generated object (the broken one)
mxcli bson dump -p app.mpr -o "PgTest.BrokenPage" > broken.json
# Dump the Studio Pro-generated object (the fixed one)
mxcli bson dump -p app.mpr -o "PgTest.FixedPage" > fixed.json
# Compare the two
diff broken.json fixed.jsonOr use the --compare flag:
mxcli bson dump -p app.mpr --compare "PgTest.BrokenPage,PgTest.FixedPage"Look for differences in:
| Area | Common Issues |
|---|---|
| Field names | caption vs CaptionTemplate, Name vs InternalName |
| Object vs value | String "" vs nested {$type: "..."} object |
| Array markers | [2, ...] vs [3, ...] for different contexts |
| Missing fields | Required fields that SDK omits |
| Type mismatches | int32 vs int64, string vs binary |
The serialization code lives in mdl/backend/modelsdk/*_write.go:
widget_write.go - Page widget serializationpage_write.go - Page document (header, parameters, layout call)microflow_write.go - Microflow activity serializationdomainmodel_write.go - Entity/attribute serializationThe encoder and decoder underneath them are modelsdk/codec/encoder.go and
modelsdk/codec/decoder.go.
Mendix uses version markers at the start of arrays:
// empty array (version 3 marker)
bson.A{int32(3)}
// non-empty array - context dependent!
// parameters arrays use version 2
bson.A{int32(2), item1, item2, ...}
// Texts$Text.Items arrays use version 3
bson.A{int32(3), item1, item2, ...}Critical: The version marker differs by context. Always check a working Studio Pro example.
Some fields expect nested objects, not simple values:
// WRONG: string value
{key: "FallbackValue", value: ""}
// CORRECT: Nested Texts$text object
{key: "Fallback", value: bson.D{
{key: "$ID", value: idToBsonBinary(generateUUID())},
{key: "$type", value: "Texts$text"},
{key: "Items", value: bson.A{int32(3)}},
}}Always use exact field names from Studio Pro:
// WRONG: Simplified name
{key: "caption", value: caption}
// CORRECT: full field name
{key: "CaptionTemplate", value: caption}Used for templated text like button captions with parameters:
func serializeClientTemplate(ct *pages.ClientTemplate) bson.D {
captionID := ct.ID
if captionID == "" {
captionID = generateUUID()
}
// build template text
template := bson.D{
{key: "$ID", value: idToBsonBinary(generateUUID())},
{key: "$type", value: "Texts$text"},
{key: "Items", value: bson.A{int32(3), /* TextItem objects */}},
}
// build fallback (required, even if empty)
fallback := bson.D{
{key: "$ID", value: idToBsonBinary(generateUUID())},
{key: "$type", value: "Texts$text"},
{key: "Items", value: bson.A{int32(3)}}, // empty fallback
}
// build parameters array
params := bson.A{int32(3)} // empty by default
if len(ct.Parameters) > 0 {
params = bson.A{int32(2)} // non-empty uses version 2!
for _, param := range ct.Parameters {
params = append(params, serializeClientTemplateParameter(param))
}
}
return bson.D{
{key: "$ID", value: idToBsonBinary(captionID)},
{key: "$type", value: "Forms$ClientTemplate"},
{key: "Fallback", value: fallback}, // Must be object, not string
{key: "parameters", value: params},
{key: "template", value: template},
}
}// in serializeActionButton:
{key: "CaptionTemplate", value: caption}, // not "caption"!mxcli bson dump reads the raw unit and prints it as JSON — no Go program needed:
# what is in there
mxcli bson dump -p app.mpr --type page --list
# one object
mxcli bson dump -p app.mpr --type page --object "MyModule.MyPage"
# the comparison that actually finds the bug: Studio Pro's vs mxcli's
mxcli bson dump -p app.mpr --type page --compare "MyModule.Broken,MyModule.Working"
# a byte-exact baseline to diff against later
mxcli bson dump -p app.mpr --type page --object "MyModule.MyPage" --format bson > baseline.mxunit--type also takes microflow, nanoflow, enumeration, snippet, layout
and constant.
mxcli bson dump -p app.mpr --type page --list
mxcli bson dump -p app.mpr --type microflow --list
mxcli bson dump -p app.mpr --type page --object "PgTest.MyPage"
mxcli bson dump -p app.mpr --type page --object "PgTest.MyPage" > mypage.json
mxcli bson dump -p app.mpr --type page --compare "PgTest.Broken,PgTest.Fixed"
## Part 5: Checklist for BSON Fixes
Before considering a fix complete:
- [ ] Create reference object manually in Studio Pro
- [ ] Dump both BSON structures (SDK vs Studio Pro)
- [ ] Identify all differences
- [ ] Fix field names to match Studio Pro exactly
- [ ] Fix object structures (nested vs value)
- [ ] Fix array version markers
- [ ] Test: Create object via MDL, verify in Studio Pro
- [ ] Update documentation (`docs/05-mdl-specification/10-bson-mapping.md`)
## Part 6: Common Issues and Solutions
| Symptom | Likely Cause | Solution |
|---------|--------------|----------|
| "(Empty caption)" in Studio Pro | Wrong field name or structure | Check `CaptionTemplate` vs `caption`, verify nested object |
| Parameters not showing | Wrong array version marker | Use `[2, ...]` for non-empty Parameters |
| Template text missing | Missing Texts$Text structure | Ensure proper TextItem serialization |
| Fallback empty | Using string instead of object | Use `Fallback` with Texts$Text object |
| Widget property ignored | Field name mismatch | Compare with Studio Pro BSON exactly |
| Columns not in Page Explorer | Incomplete nested WidgetObjects | Create ALL properties from template |
| TypeCacheUnknownTypeException | Wrong BSON $Type name | Use `Texts$Translation` not `Texts$TextItem` |
| CE0642 "Property is required" | Wrong value format or missing | Check ValueType.Type in template, use correct BSON field |
| NullReferenceException in GetExpectedExpressionType | Using Expression for non-Expression type | Use `PrimitiveValue` for Boolean/Enum/Integer types |
| CE0495 Duplicate name errors | Same widget in multiple properties | Set content/filter to empty widget arrays |
## Part 7: Nested WidgetObjects (Critical)
**Key Insight**: Pluggable widgets with nested objects (like DataGrid2 columns) require **ALL properties** to be created, not just the ones with explicit values.
### The Problem
When creating nested `WidgetObject` instances (e.g., DataGrid2 columns), creating only the properties with explicit values results in:
- Objects that don't appear in the Page Explorer
- CE0463 "widget definition has changed" errors
- Widgets that render in the editor but are incomplete
### Example: DataGrid2 Columns
**Symptom**: Columns show in the page editor but NOT in the Page Explorer tree.
**Cause**: Column objects have 5 properties instead of the required 21.
```bash
# Compare mxcli-generated vs Studio Pro-generated
mxcli bson dump -p app.mpr --compare "PgTest.MDLPage,PgTest.StudioProPage"
# Look for property count differences:
# ~ properties: array length differs (first: 5, second: 22)Solution: The embedded templates at sdk/widgets/templates/mendix-11.6/datagrid.json contain all 21 column properties:
showContentAs, attribute, content, dynamictext, exportValue, header, tooltip,
filter, visible, sortable, resizable, draggable, hidable, allowEventPropagation,
width, minWidth, minWidthLimit, size, alignment, columnClass, wrapTextWhen building columns, iterate through ALL PropertyTypes in the template's ObjectType and create a WidgetProperty for each one, using default values for properties without explicit values.
Count properties in both versions:
mxcli bson dump -p app.mpr --type page --object "PgTest.BrokenPage" | grep "WidgetProperty" | wc -l
mxcli bson dump -p app.mpr --type page --object "PgTest.FixedPage" | grep "WidgetProperty" | wc -lCheck the template for required properties:
grep '"PropertyKey"' sdk/widgets/templates/mendix-11.6/datagrid.json | head -30Compare specific nested objects using --compare flag to find property count mismatches.
Key Insight: Pluggable widget properties require different value formats based on their ValueType.Type field in the widget template. Using the wrong format causes CE0642 "Property is required" errors or NullReferenceException.
Check the ValueType.Type field in the widget template JSON:
{
"PropertyKey": "visible",
"ValueType": {
"type": "expression",
"ReturnType": "boolean"
}
}| ValueType.Type | BSON Field | Example Value | Notes |
|---|---|---|---|
expression | expression | "true", "$currentObject/Name" | String expression, NOT evaluated |
boolean | PrimitiveValue | "true", "false" | String representation |
enumeration | PrimitiveValue | "left", "autofill" | Enum value name |
integer | PrimitiveValue | "100", "0" | String representation |
decimal | PrimitiveValue | "10.5" | String representation |
string | PrimitiveValue | "text value" | Direct string |
widgets | widgets | bson.A{...} | Array of widget objects |
object | objects | bson.A{...} | Array of WidgetObject |
// WRONG: Using expression for boolean-type property
// Causes: NullReferenceException in GetExpectedExpressionType
{key: "sortable", value: bson.D{
{key: "expression", value: "true"}, // WRONG!
}}
// CORRECT: Using PrimitiveValue for boolean-type property
{key: "sortable", value: bson.D{
{key: "PrimitiveValue", value: "true"}, // Correct!
}}| Property | ValueType.Type | BSON Field | Default Value |
|---|---|---|---|
visible | Expression | expression | "true" |
sortable | Boolean | PrimitiveValue | "true" |
resizable | Boolean | PrimitiveValue | "true" |
draggable | Boolean | PrimitiveValue | "true" |
wrapText | Boolean | PrimitiveValue | "false" |
hidable | Enumeration | PrimitiveValue | "yes" |
alignment | Enumeration | PrimitiveValue | "left" |
width | Enumeration | PrimitiveValue | "autofill" |
minWidth | Enumeration | PrimitiveValue | "auto" |
size | Integer | PrimitiveValue | "100" |
header | Object | objects | Empty translation |
content | Widgets | widgets | Empty widget array |
filter | Widgets | widgets | Empty widget array |
| Error | Cause | Solution |
|---|---|---|
| CE0642 "Property 'X' is required" | Missing property or wrong value format | Check ValueType.Type, use correct BSON field |
| NullReferenceException in GetExpectedExpressionType | Using expression for non-Expression type | Use PrimitiveValue for Boolean/Enum/Integer |
| CE0463 "widget definition has changed" | Missing properties | Create ALL properties from template |
# check the embedded widget template
grep -A5 '"PropertyKey": "visible"' sdk/widgets/templates/mendix-11.6/datagrid.json
# or use jq to extract all property types
jq '.PropertyTypes[] | {key: .PropertyKey, type: .ValueType.Type}' sdk/widgets/templates/mendix-11.6/datagrid.jsonCritical: The correct type for translatable text items is Texts$Translation, NOT Texts$TextItem.
TypeCacheUnknownTypeException: The type cache does not contain a type with qualified name Texts$TextItem// WRONG: Texts$TextItem does not exist
{key: "$type", value: "Texts$TextItem"}
// CORRECT: use Texts$Translation with LanguageCode
{key: "$type", value: "Texts$Translation"},
{key: "LanguageCode", value: "en_US"},
{key: "text", value: "Your text here"},headerTranslation := bson.D{
{key: "$ID", value: idToBsonBinary(generateUUID())},
{key: "$type", value: "Texts$Translation"},
{key: "LanguageCode", value: "en_US"},
{key: "text", value: columnHeader},
}
headerText := bson.D{
{key: "$ID", value: idToBsonBinary(generateUUID())},
{key: "$type", value: "Texts$text"},
{key: "Items", value: bson.A{int32(3), headerTranslation}},
}CE0463 "widget definition has changed" is one of the most common errors when creating pluggable widgets programmatically. For filter widgets, this error is often caused by TextTemplate properties being null instead of proper Forms$ClientTemplate structures.
Check the Type section for properties with "type": "TextTemplate":
{
"PropertyKey": "placeholder",
"ValueType": {
"$ID": "abc123...",
"$type": "CustomWidgets$WidgetValueType",
"type": "TextTemplate" // <-- This is a TextTemplate property
}
}Find the matching Object property using the TypePointer:
{
"TypePointer": "abc123...", // Matches ValueType.$ID above
"value": {
"TextTemplate": null // <-- WRONG! Causes CE0463
}
}Every TextTemplate property must have this structure (never null):
"TextTemplate": {
"$ID": "<32-char-guid>",
"$type": "Forms$ClientTemplate",
"Fallback": {
"$ID": "<32-char-guid>",
"$type": "Texts$text",
"Items": []
},
"parameters": [],
"template": {
"$ID": "<32-char-guid>",
"$type": "Texts$text",
"Items": []
}
}WRONG - [2] in JSON serializes as an array containing the integer 2:
"Items": [2] // Creates array with one element: the number 2
"parameters": [2] // Creates array with one element: the number 2CORRECT - Use truly empty arrays:
"Items": [] // Truly empty array
"parameters": [] // Truly empty arrayThe version markers (like [2] or [3]) only exist in BSON wire format, not in JSON template files.
| Widget | TextTemplate Properties |
|---|---|
| TextFilter | placeholder, screenReaderButtonCaption, screenReaderInputCaption |
| DateFilter | placeholder, screenReaderButtonCaption, screenReaderCalendarCaption, screenReaderInputCaption |
| DropdownFilter | emptyOptionCaption, ariaLabel, emptySelectionCaption, filterInputPlaceholderCaption |
| NumberFilter | placeholder, screenReaderButtonCaption, screenReaderInputCaption |
Use this script to identify which Object properties need TextTemplate structures:
import json
with open('widget-template.json') as f:
data = json.load(f)
# Extract ValueType IDs for TextTemplate properties
text_template_ids = {}
for prop_type in data['type']['ObjectType']['PropertyTypes']:
vt = prop_type.get('ValueType', {})
if vt.get('Type') == 'TextTemplate':
text_template_ids[vt['$ID']] = prop_type['PropertyKey']
print("TextTemplate properties:", text_template_ids)
# find matching object properties with null TextTemplate
for prop in data['object']['Properties']:
type_ptr = prop['Value'].get('TypePointer')
if type_ptr in text_template_ids:
text_template = prop['Value'].get('TextTemplate')
if text_template is none:
print(f"NEEDS FIX: {text_template_ids[type_ptr]} (TypePointer: {type_ptr})")After fixing templates:
mx check app.mpr - should return 0 errorsPart 10 above covers writing Forms$ClientTemplate. The same structure applies when reading it in executor code (e.g. cmd_alter_page.go, cmd_pages_describe_output.go).
The correct traversal is:
TextTemplate (Forms$ClientTemplate) → Template (Texts$Text) → Items[] → Translation { Text }Do not read Items directly off the TextTemplate document — that skips the intermediate Template node and silently returns an empty slice. Always traverse one level deeper:
// WRONG — Items is always empty
items := dGetArrayElements(dGet(tmplDoc, "Items"))
// CORRECT — traverse Template first
template := dGetDoc(tmplDoc, "Template")
items := dGetArrayElements(dGet(template, "Items"))This applies to any executor function that reads column headers, button captions, or any other translatable text stored as Forms$ClientTemplate.
# 1. find the broken object
mxcli -p app.mpr -c "describe page PgTest.BrokenPage"
# 2. create fixed version in Studio Pro, save project
# 3. Dump both objects to json files
mxcli bson dump -p app.mpr --type page --object "PgTest.BrokenPage" > broken.json
mxcli bson dump -p app.mpr --type page --object "PgTest.FixedPage" > fixed.json
# 4. Compare the json files
diff broken.json fixed.json
# or use a visual diff tool like VS Code:
code --diff broken.json fixed.json
# 5. after fixing code, verify
go build ./... && mxcli exec test.mdl -p app.mpr
# 6. Verify in Studio Pro (open project, check object)| File | Purpose |
|---|---|
mdl/backend/modelsdk/widget_write.go | Page widget BSON serialization |
mdl/backend/modelsdk/microflow_write.go | Microflow BSON serialization |
mdl/backend/modelsdk/domainmodel_write.go | Entity BSON serialization |
modelsdk/codec/encoder.go | Document → BSON |
modelsdk/codec/decoder.go | BSON → document |
docs/05-mdl-specification/10-bson-mapping.md | BSON format documentation |
© mendixlabs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/mendix/debug-bson of mendixlabs/mxcli.
Open the folder on GitHubat commit a924d11
Debug Bson next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Debug Bson this skillmendixlabs/mxcli | 128 | — | ~5.2k | Automated safety check: Pass | Apache-2.0 | |
| Trellis Session Insightmindfold-ai/Trellis | 15k | 4 repos | ~1.7k | Automated safety check: Pass | AGPL-3.0 | |
| Native Data FetchingCherryHQ/cherry-studio-app | 4k | 6 repos | ~2.9k | Automated safety check: Notes | MIT | |
| Aoti Debugpytorch/pytorch | 104k | 1 repos | ~1.7k | Automated safety check: Pass | Custom licence | |
| Herdr Throwaway Reproductionherdrdev/herdr | 43k | — | ~2.4k | Automated safety check: Pass | Apache-2.0 | |
| Systematic Debuggingultralisp/ultralisp | 258 | 51 repos | ~2.4k | Automated safety check: Pass | None |
mindfold-ai/Trellis
Reach into past AI conversation history through the trellis mem CLI.
CherryHQ/cherry-studio-app
A skill your agent uses when implementing or debugging ANY network request, API call, or data fetching.
pytorch/pytorch
Debug AOTInductor (AOTI) errors and crashes. An agent skill from pytorch/pytorch.
herdrdev/herdr
Runs a disposable, uniquely named Herdr session inside an existing one so runtime, pane, terminal or API bugs can be reproduced without touching the main session.
ultralisp/ultralisp
A skill your agent uses when encountering any bug, test failure, or unexpected behavior, before proposing fixes
AprilNEA/OpenLogi
Decides whether an OpenLogi device problem on macOS is a privacy-permission (TCC) problem, using agent log lines, and says which identity needs which grant.
mendixlabs/mxcli
Push OData query options into the SQL of a Mendix resource served by a read microflow, so $filter, $orderby, $top, $skip, $count and the key lookup reach the database instead of being silently…
mendixlabs/mxcli
Chart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload.
mendixlabs/mxcli
Author Mendix AI agent documents in MDL — Model, Knowledge Base, Consumed MCP Service and Agent, with variables, tools and multi-line prompts.
mendixlabs/mxcli
Run set-based INSERT, UPDATE and DELETE against Mendix entities through OQL statements, which the runtime supports and Studio Pro cannot author.
mendixlabs/mxcli
Stand up an HTTP endpoint you control instead of a live third-party API, and point the Mendix app at it — Prism from an OpenAPI contract, a constant swap, or a forward proxy.
mendixlabs/mxcli
Call external REST APIs from Mendix — the three approaches (inline REST CALL, consumed REST client document, generated from OpenAPI) and how to choose.
Categories
Diagnose BSON serialization problems in the MPR file — missing properties, wrong storage names, widget definitions Studio Pro rejects. Debug Bson is an agent skill from mendixlabs/mxcli. Diagnose BSON serialization problems in the MPR file — missing properties, wrong storage names, widget definitions Studio Pro rejects.
Debug Bson fits situations like: something created through MDL does not appear correctly in Studio Pro; A CE error points at a document mxcli wrote.
Run `npx skills add mendixlabs/mxcli --skill debug-bson -a claude-code`. Or copy the skill folder (.claude/skills/mendix/debug-bson in mendixlabs/mxcli) into .claude/skills/debug-bson in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mendixlabs/mxcli --skill debug-bson -a codex`. Or copy the skill folder (.claude/skills/mendix/debug-bson in mendixlabs/mxcli) into .agents/skills/debug-bson in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mendixlabs/mxcli --skill debug-bson -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/debug-bson, .gemini/skills/debug-bson, .github/skills/debug-bson and .opencode/skills/debug-bson in your project.
Going by SKILL.md and its folder, Debug Bson needs the command-line tools its instructions call (jq and go).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Debug Bson is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.2k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Debug Bson: Trellis Session Insight (mindfold-ai/Trellis, 15k stars), Native Data Fetching (CherryHQ/cherry-studio-app, 4k stars), Aoti Debug (pytorch/pytorch, 104k stars) and Herdr Throwaway Reproduction (herdrdev/herdr, 43k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mendixlabs (a GitHub organization) maintains it in mendixlabs/mxcli, which has 128 GitHub stars. The repository holds 75 skills in this directory. The repository was last updated on October 7, 2026.
Source: mendixlabs/mxcli on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.