Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bae86f4
deps(vscode-mdl): fix the msal-node and qs advisories
claude Nov 11, 2026
d83409b
deps(vega-charts widget): fix the zod advisory
claude Nov 11, 2026
04a1885
Merge pull request #2126 from ako/deps/audit-fixes
ako Nov 11, 2026
53899c6
catalog: record Excluded for snippets and layouts
claude Nov 11, 2026
f822dee
pages: write the data view's parameter beside it in a flow argument
claude Nov 11, 2026
2388d02
fix(run): make the serve build and runtime start limits configurable
claude Nov 11, 2026
2d7a61d
pages: bind a primitive page parameter in a text template
claude Nov 11, 2026
90cfc16
fix(run): offer the 11.15.0 upgrade only for the serve-build failure …
claude Nov 11, 2026
d090785
feat(run): run clear-sessions frees the unlicensed runtime's 6 sign-i…
claude Nov 11, 2026
cd2cfe9
fix(run --watch): recheck an incremental CE0108 on a fresh mxbuild --…
claude Nov 11, 2026
7930fc2
catalog: store an absent agent-editor reference as NULL, not ''
claude Nov 11, 2026
fd51d9f
fix: check reports access-rule XPath constraints that mxbuild rejects…
claude Nov 11, 2026
de7e18d
fix: alter workflow reports a user task left with one outcome holding…
claude Nov 11, 2026
1edbc6b
docs(skill): keep run-local under the 700-line body limit
claude Nov 11, 2026
e7ec350
pages: bind an association path read from a parameter ($Param/Assoc/A…
claude Nov 11, 2026
cc7bada
test: add the mdl 1; header to the #2099 bug-test script
claude Nov 11, 2026
89e03a2
fix: check reports a call argument whose type cannot match the parame…
claude Nov 11, 2026
d88e9e3
fix: check reports a menu item that calls a flow or page needing a pa…
claude Nov 11, 2026
6541778
fix: write a widget attribute path through a specialization as a step…
claude Nov 11, 2026
75b2a3a
fix: alter styling warns on a design property the widget's own type d…
claude Nov 11, 2026
3c5c22d
fix(check): refuse message definition collections on 11.15+ at check …
claude Nov 11, 2026
ebe29e6
fix(versions): keep a feature's max_version when YAML files share its…
claude Nov 11, 2026
9c6bb19
docs(syntax): lead message-definition with the 11.15+ document form (…
claude Nov 11, 2026
4270b23
Merge pull request #2143 from ako/claude/hopeful-babbage-9s5rdg
ako Nov 11, 2026
97858ec
pages: keep the specialization step of an association path
claude Nov 11, 2026
e64d9de
bug-tests: use the canonical 'close page' spelling
claude Nov 11, 2026
4556fe6
roundtrip: strike the TestApp snippets this branch fixed from knownFa…
claude Nov 11, 2026
1c942f9
docs: access-rule examples use the [%CurrentUser%] token, not $curren…
claude Nov 11, 2026
470ba9e
Merge pull request #2142 from ako/claude/check-mxbuild-drift-issues-w…
ako Nov 11, 2026
8e5a040
Merge pull request #2144 from ako/claude/mxcli-issues-2139-2140-otfhco
ako Nov 11, 2026
fe89762
Merge pull request #2141 from ako/claude/beautiful-thompson-96trn4
ako Nov 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-11", "symptom": "`run --local` could not start a 188-module, 12,900-document app (Mendix 10.24.26): the cold first build failed with \"serve build request ... context deadline exceeded (Client.Timeout exceeded while awaiting headers)\" at a fixed 10 minutes, and the runtime start failed with \"cannot connect to Mendix admin API at 127.0.0.1:24811 -- is the app running?\" while the after-startup microflow was still running, after which mxcli shut the runtime down. Neither limit had a flag or an environment variable.", "cause": "ServeServer.Build used http.Client{Timeout: 10 * time.Minute}; StartLocalRuntime gave the M2EE connection a 150 s timeout that bounded every admin call, including `start`, which does not answer until the after-startup action returns. callM2EEDirect reported any client error, a timeout included, as an unreachable app.", "file": "cmd/mxcli/docker/mxserve.go (BuildTimeout, serveBuildTimeout, durationSetting), cmd/mxcli/docker/runtime_controller.go (StartTimeout, callStartPhase), cmd/mxcli/docker/m2ee.go (timeout is 'did not answer', isAdminTimeout), cmd/mxcli/cmd_run.go (--build-timeout, --start-timeout)", "insight": "A per-connection timeout is the wrong unit when one action on the connection is a different kind of call: `start` and `execute_ddl_commands` run user code and a schema update, every other admin action is a quick query. Give the long ones their own limit and keep the short one for the rest, so a hung status probe still fails fast. And a timeout is the server holding the request, not refusing it: reporting it as 'is the app running?' sent the user looking for a dead process in a live one. The isTimeout helper buildRetryingServeTimeout already used is the seam for both; wrap with %w so the retry still recognises the error. Control: with the limits stubbed back to 10m/150s and the timeout branch disabled, the two behaviour tests fail and the start test prints the reported 'cannot connect ... is the app running?' text.", "refs": ["mendixlabs/mxcli#1818", "ako/mxcli#2136"], "test": "cmd/mxcli/docker/run_timeouts_test.go"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-11", "symptom": "mendixlabs/mxcli#1810 (ako/mxcli#2129): under `run --local` with security on, Playwright probes that sign in once each and never sign out exhaust the unlicensed runtime's sessions; sign-ins 1-6 answer 200, the 7th and later HTTP 560 'Sign in failed', runtime log 'Maximum number of sessions exceeded! (You are currently using a trial license)'. mxcli had no way to free them short of stopping the app and deleting from \"system$session\" by hand.", "cause": "The trial licence caps concurrent sessions at 6 and counts the System.Session rows in the database. Each sign-in holds a row until sign-out or expiry; a probe loop fills them in seconds. Nothing in `mxcli run` deleted them.", "file": "cmd/mxcli/cmd_run_sessions.go (run clear-sessions, runDatabaseFromArgs), cmd/mxcli/docker/sessions_clear.go (ClearSessions, clearSessionRows), cmd/mxcli/docker/runlocal.go (RunDatabase), cmd/mxcli/docker/screenshot_login.go (hint names the command)", "insight": "Measure before building on the report's theory. The first fix cleared System.Session at boot, on the report's claim that rows outlive a restart (20 had piled up). On 11.12.1 the rows do survive a graceful stop (6 left), but the runtime logs 'Deleting old sessions from database...' as it starts and boots with 0, so the boot clear was redundant and the old hint's 'restart clears them' was right. The question that mattered was whether the cap is counted in memory or in the table: deleting the rows from a LIVE app made the next sign-in succeed, so a no-restart command is possible. Run it end to end with curl against /xas/ login (no browser needed: each curl without a cookie jar is a fresh session): 6x200, 560, control 560 without clearing, clear-sessions, 6x200. The real schema also has FKs (session_user ON DELETE CASCADE, backgroundjob/changehash SET NULL), so a plain delete is safe. Infra trap: a Postgres data dir under the 0700 session scratchpad PANICs mid-test when the tree's perms are tightened; put it in /var/tmp.", "refs": ["mendixlabs/mxcli#1810", "ako/mxcli#2129"], "test": "cmd/mxcli/cmd_run_sessions_test.go, cmd/mxcli/docker/sessions_clear_test.go, cmd/mxcli/docker/sessions_clear_integration_test.go"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-11", "symptom": "ako/mxcli#606 follow-up: after 11.15.0 was measured to fix the 11.14 warm-loop failure (BankV1, Linux, builds #2-#4 in 2.8-3.9 s), the remaining ask was for mxcli's hint and the bootstrap default to point at 11.15.0 as the fix. The hint still said only 'On Mendix 11.12.5 and 11.14 ... drop --watch and restart per change'.", "cause": "One hintText served two different failures: the bundler-config one (ERR_MODULE_NOT_FOUND web/rollup.config.mjs or rspack.config.mjs) and the per-document client one (web/pages/, web/layouts/). They share a symptom class but not a remedy: the first is gone on 11.15.0, the second was recorded on macOS 11.15.0 (fixture real1115MacOSMissingClientDirsByKey, 2026-11-06).", "file": "cmd/mxcli/docker/webclient_legacy_paths.go (hintText takes the per-half version line), .claude/skills/mendix/bootstrap-app/SKILL.md (skip a cached 11.14.x), docs-site/src/tools/run-local.md", "insight": "Before writing 'fixed in X' into a hint, grep the test fixtures for X: the issue comment said 11.15.0 fixed it, and a fixture three weeks younger showed half of it still failing on 11.15.0 macOS. The comment measured the half it happened to hit. Writing the upgrade advice for both halves would have been a wrong diagnosis printed under every macOS failure. Control: the new test fails against the old single hint on both assertions (no 11.15.0 on the config half, no 11.15 on the client half).", "refs": ["ako/mxcli#606"], "test": "cmd/mxcli/docker/webclient_legacy_paths_test.go"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli/syntax","date":"2026-11-11","symptom":"`mxcli syntax message-definition` documented only `CREATE … MESSAGE DEFINITION COLLECTION`, which an 11.15+ project refuses, and its Requires block said `Mendix 10.0.0+` for the collection; the 11.15 document form appeared only in an exec hint, and a user wrote its folder clause after FOR (`… for Shop.ApiTicket folder 'Api' { … }` -> \"mismatched input 'folder' expecting {AS, '(', '{'}\") and concluded it had none","cause":"The syntax entry was written for the collection and never updated when #987 added the document form. Separately, sdk/versions dedup() merged mendix-10.yaml's and mendix-11.yaml's message_definition_collection entries (same 10.0.0 floor) keeping the FIRST — the one without max_version: 11.14.99 — so IsAvailable said the collection exists on 11.16 and the syntax page could not show the ceiling","file":"`cmd/mxcli/syntax/features_integration.go` (document form first, collection marked 11.14-and-earlier); `cmd/mxcli/syntax/format.go`/`versions.go` (Requirement.Until rendered as `10.0.0 to 11.14.99`); `sdk/versions/registry.go` dedup prefers the entry that states a max_version","insight":"The FOLDER clause existed all along (name, FOLDER, then FOR — the order of every document statement, and what describe prints); before adding a second clause position for a 'missing' clause, try it where describe puts it. A max_version in one per-major YAML is silently lost when another file lists the same floor without one: any ceiling added to a feature that an older file also lists needs a registry test, as TestMessageDefinitionCollectionEndsAt1114 now is.","refs":["ako/mxcli#2140","ako/mxcli#987"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-11", "symptom": "ako/mxcli#2064: under `run --local --watch` (Mendix 11.16.0) an incremental mxbuild --serve build failed with CE0108 \"Variable 'Latest' is defined but not in scope at this location\" on an mxcli-written microflow (a variable a call creates, used after a decision), while `docker check` reported 0 errors and the next build on a fresh serve process applied the same model. Three times in one session, not deterministic; the loop stayed on 'build #N FAILED' until something forced a full build.", "cause": "mxbuild --serve's incremental state, as far as can be told: the same bytes pass a full build. serveRecovery already restarted serve for failures known to be process state (the 11.14 client-source shape, a stale CE6093 theme error) but took every other failure as the model's.", "file": "cmd/mxcli/docker/serve_recovery.go (incrementalScopeErrors, recheckIncrementalErrors, confirmedErrors)", "insight": "The verdict on a suspect failure belongs to the tool, not to a heuristic: rebuild on a fresh process and let that answer stand, which is the stale-theme pattern already in serveRecovery. Two costs to bound: scope it to codes actually seen lying (CE0108 only), since each recheck is a ~25 s cold build on a genuine error; and remember a fresh-process-confirmed error signature so a user fixing a real CE0108 pays one recheck, not one per save, cleared by the next passing build. Callers route only post-boot builds through serveRecovery, so 'not restartPending' means incremental. Control: with the branch disabled, the scripted test returns the incremental CE0108 although the full build passed. Not reproduced live: the report is non-deterministic.", "refs": ["ako/mxcli#2064"], "ce": ["CE0108"], "test": "cmd/mxcli/docker/serve_recovery_scope_test.go"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-11-11", "refs": ["ako/mxcli#2099", "mendixlabs/mxcli#1803", "mendixlabs/mxcli#1472"], "ce": ["CE0161"], "rules": ["MDL-XPATH04", "MDL047", "MDL-XPATH01"], "symptom": "An access rule WHERE whose members all resolve passed check -p and exec and failed mx check (11.14.0, Production) with CE0161 \"Error(s) in XPath constraint.\" at Access rule of entity: [Title = $x], [M.E_Kid = empty], [Title = '[%CurrentUser%]'], [Cnt = '5'], [Status = 'red'], [System.owner = '[%CurrentUser%]'] on an entity without owner, [E_Kid/M.Kid/Name = 'a'].", "file": "mdl/executor/validate_access_rule_xpath.go (new: accessRuleXPathFormViolations from ValidateGrantEntityAccess; grantResolver.xpathFormProblems from validate_grant_refs.go check()); test validate_access_rule_xpath_test.go", "cause": "#1472's grantResolver.xpathProblem only asked whether members resolve. The form rules the retrieve and widget slots had (MDL047, MDL-XPATH01, the System-member rule) were never called for the grant slot, and nothing anywhere typed a literal against its attribute.", "insight": "Measure with one entity + one access rule per constraint in ONE app: mxbuild attributes each CE0161 to 'Access rule of entity X', so 86 forms cost two 17-second mx checks instead of 86. The matrix overturned three guesses: an access rule takes NO variable at all ($currentUser included - the token is the spelling); any string literal on a DateTime builds ('abc' too) while a Boolean takes 'true'/'false' in any case but not 'yes'; a decimal literal on an Integer builds while '5' does not. Enumeration literals match value NAMES case-sensitively (the caption 'Green' fails, the key 'Grn' builds) - the opposite of member names, which mxbuild folds. Reuse was cheap because validateXPathAssociations and validateRetrieveConstraints take a []retrieveConstraintRef: a grant is a one-element slice. Run the form rules only once xpathProblem is clean - a standing CE1613 suppresses every CE0161. Left silent: tokens other than [%CurrentUser%] (a date token on an Integer is CE0161 too), attributes reached over a path, and a token on an association to a non-User entity."}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-11-11", "refs": ["ako/mxcli#613", "ako/mxcli#509", "ako/mxcli#515", "ako/mxcli#511"], "ce": ["CE6083"], "rules": ["MDL-WIDGET11"], "symptom": "alter styling on page MyFirstModule.HideOn widget dt set 'Row size' = 'Small' (a ListView key on a Forms$DynamicText) -> mxcli check -p --references: Check passed! (no MDL-WIDGET11); mxcli docker check: [CE6083] \"Design property Row size is not supported by your theme.\" at Text 'dt'. The same key on the ListView lvH: 0 errors.", "cause": "validateAlterStylingDesignProps runs in ValidateProgram with no document, so it asked only whether ANY widget type declares the key; the widget's $Type lives in the stored page.", "file": "mdl/executor/validate_alter_styling_stored.go (validateAlterStylingStoredTypes, reference pass, wired in validate.go); validate_alter_set.go (pageProbe now embeds widgetStorageTyper); design_property_routing.go (designPropsKeyOfStored, documentThemeOf). Tests: validate_alter_styling_stored_test.go", "insight": "**The first attempt passed every mock-backend test and did nothing on a real project:** it opened the page from ValidateProgram's lazy project, and openProjectForValidation's read-only modelsdk connection refuses OpenPageForMutation (\"not connected for writing\") — MockBackend's OpenPageForMutationFunc does not, so only `check -p` against a real 11.14.0 app showed the precise path silently falling back. Anything that opens a document for a check belongs in the reference pass (validateProgramWithWarnings, implied by -p and run by exec's preflight), which validateAlterSetProperties and validateStoredSnippetCallAppearance already use. Split by KEY to avoid double reports: the any-type pass keeps keys no type declares, the stored pass judges only keys the first accepted, with validateDesignPropsAs's exact condition (findThemeProp, rename, declaresGroup guard) so ALTER STYLING and CREATE PAGE cannot disagree. No new resolver: designPropsKeyOfStored is storedWidgetDesignPropsKey's body, shared. Controls: stubbing resolve() fails TestAlterStyling613_KeyOfAnotherWidgetTypeIsReported with 'got 0'; real run warns on dt and is silent on lvH; mx check 1 error vs 0."}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-11-11","symptom":"`alter workflow` leaving a user task with one outcome that holds activities (dropping its other outcome, or inserting such a task) passed `check -p` and `exec`; mx check 11.14.0 then CE1876 \"Single outcome must not contain any activities in its flow.\" — while `create workflow` refused the same shape as MDL-WF02","cause":"ValidateAlterWorkflow skipped WF02 deliberately because a later op can still add the second outcome, so no alter was ever judged — a correct concern answered by not checking at all","file":"mdl/executor/validate_workflow_single_outcome.go (validateAlterWorkflowSingleOutcomes, wired in ValidateProgram)","insight":"When a per-statement rule is skipped because 'a later op may repair it', the fix is to move the rule to the scope where the repair is visible — a script-level replay over a small model of the affected state — not to keep skipping it. Baseline preference: the script's own CREATE (makes it decidable without -p, so the corpus can carry a .fail.mdl), then the stored document, then nothing (only inserted tasks known → a stored-task drop stays silent). Every op the model cannot follow (@N, an unresolved ref that may be a builder-generated name, an ambiguous name) marks the task unknown rather than guessing; that keeps the expensive direction (a false refusal now blocks exec) closed. Measured on 11.14.0 with two copies: drop -> CE1876; drop then `insert into Review { outcomes 'Escalate' { } }` in a later statement -> 0 errors.","refs":["ako/mxcli#2097","mendixlabs/mxcli#1798"],"ce":["CE1876"],"rules":["MDL-WF02"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-11-11","symptom":"describe of TestApp WorkflowCommons.Snip_Workflow_Header printed CaptionParams ({1} = System.Workflow_ParentWorkflow/Name) without its $Workflow root; exec wrote it with no source and mx check reported CE0402 'No value specified.' at actionButton1. textBox9 of Snip_WorkflowUserTaskView_Details (same shape on an input) was refused by check (MDL-WIDGET34). Also: {1} = $dv1.Name naming a non-enclosing data view was written as {Widget: dv1} (CE7001), and a page variable passed to a snippet parameter was written (CE0115)","cause":"resolveAssociationAttributePath handled only context-relative paths; a $param-rooted path was 'unsupported', and isTemplateExpression treats $Var/... as an expression (mendixlabs/mxcli#1406), whose form for an association path is CE0117. describe printed the association path from AttributeRef without the SourceVariable root. Attribute: $P/Assoc/Attr parses as a DataSourceV3 (ContextVariable), not a string, so input builders never saw it","file":"mdl/executor/cmd_pages_builder_v3.go (resolveRootedAssociationPath, resolveAssociationPathFrom), cmd_pages_template_attr.go (pb.isTemplateExpression), cmd_pages_parameter_binding.go (rootedAssociationPath, inputAttributeText), cmd_pages_describe_pluggable.go, cmd_pages_describe_parse.go, cmd_pages_input_binding_context.go","insight":"Test through the classifier, not the resolver: the first resolver-level test passed while the builder still routed $Var/Assoc/Attr to Expression, and only the TestApp round trip (CE0117) showed it. The spelling $Root/Assoc/Attr was already claimed as an expression by #1406, so the binding wins only when the root resolves (a parameter or enclosing data view) and there is an association hop, mirroring the existing $currentObject/Assoc/Attr exception; everything else stays an expression. The proof was the round trip of Studio Pro's own snippet: 'Unchanged snippet' (byte-identical) and mx check 0 errors, against CE0402 before. The remaining CE1613 on text11/text16 in the same snippet is a separate gap (a specialization DestinationEntity dropped by describe), confirmed pre-existing with the old binary.","refs":["#833"],"ce":["CE0402","CE0117","CE7001","CE0115"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-11-11","symptom":"describe -> exec of TestApp WorkflowCommons.Snip_WorkflowUserTaskView_Details: mx check CE1613 'The selected attribute System.User.FullName no longer exists.' at Text 'text11' and 'text16'","cause":"Studio Pro stores an association step whose DestinationEntity is a specialization of the association's end (System.WorkflowUserTaskOutcome_User -> Administration.Account, attribute Administration.Account.FullName). The describe readers (associationTemplateParamPath, columnAttributeFromRef) printed only the associations, and resolveAssociationPathFrom had no spelling for a cast, so the step landed on System.User","file":"mdl/executor/cmd_pages_describe_output.go (associationPathMDL, describeAssociationEnds), cmd_pages_describe_pluggable.go (columnAttributeFromRef), cmd_pages_builder_v3.go (resolveAssociationPathFrom, associationHasEnd)","insight":"A step's DestinationEntity is a cast exactly when it is neither end of its association; that test needs no direction, and describe answers it with the builder's own associationEndpoints through a bare pageBuilder, so the two halves cannot disagree about an association. Spell the cast Assoc/Module.Entity/Attr (Mendix's expression form). Before shipping a describe change, diff old vs new describe over every page and snippet of the corpora (TestApp, PedApp) and round-trip every changed document through mx check: here that turned up DataGrid2 columns printing the cast too (they came back Unchanged), and one snippet still failing because System.WorkflowSubProcess is missing from modelsdk/meta/system_module.go, which was broken before as well (CE0402 old, CE0117 now).","refs":["#833"],"ce":["CE1613"]}
Loading
Loading