Skip to content

run --local hardening, ListView database-source crash fix, and doctype version-gate#777

Merged
ako merged 4 commits into
mendixlabs:mainfrom
ako:upstream-8-9-10
Jul 22, 2026
Merged

run --local hardening, ListView database-source crash fix, and doctype version-gate#777
ako merged 4 commits into
mendixlabs:mainfrom
ako:upstream-8-9-10

Conversation

@ako

@ako ako commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Three changes on top of what’s already in main.

  1. mxcli run --local — refuse stale ports, watch theme source, log build generation
    Fixes the “my SCSS/model edit doesn’t show up” class of problems in the warm dev loop — none of which were a compiled-CSS cache:
    • Stale-process guard: run --local now refuses to boot when its ports (8080/8090/6543) are already answering. Previously the readiness probes only checked that the port responded, so a leftover mxbuild --serve/runtime was silently adopted and kept serving old output. Detect only — never kills another process.
    • Theme source is now watched: the --watch signal covers theme/ and themesource/** (SCSS/CSS/JS) in addition to the model, via mtime polling (container-safe, no inotify dependency). Previously a theme edit triggered no rebuild even under --watch.
    • Build-generation logging: each apply logs build #N so “did my change take?” is answerable from the log.
    • Docs (docs-site/src/tools/run-local.md + synced skill): SCSS needs a rebuild (--watch or a clean restart), never a cache-clear.
  2. ListView database source runtime crash
    A native ListView over a database from (XPath) datasource passed mx check but crashed the browser client on load (Cannot read properties of undefined (reading 'length') in retrieveByXPath/processResult). The Forms$ListViewXPathSource omitted the lists the client reads .length of:
    • Codec (default): Forms$ListViewSearch was emitted without its SearchRefs list — the encoder drops an empty, never-Set PartList unless the $Type is registered (as GridSortBar.SortItems was, but ListViewSearch wasn’t).
    • Legacy: wrote a bogus Forms$ListViewSort + a Paths key (renamed SearchRefs in 7.11.0) and no GridSortBar.
    Both engines now emit the correct GridSortBar/SortItems + ListViewSearch/SearchRefs + ForceFullObjects. The pluggable Gallery/DataGrid2 source was already correct and is unchanged. Validated fixed in a real app.
  3. Version-gate the parameter page in the alter-page-insert-into doctype
    The nightly builds its shared source project with Mendix 10.24, but alter-page-insert-into.mdl created a page with params: {...} — an 11.0+ feature — so the executor refused on 10.x. The parameter-dependent case is moved to the end under a single -- @Version: 11.0+ gate; the two container cases stay ungated, so INSERT INTO is still exercised on 10.x.
    Testing
    • go build ./..., go vet, gofmt clean; mdl/backend/modelsdk and sdk/mpr suites pass; run-local unit tests (TestCheckTargetPortsFree, TestThemeSourceMTime_...) pass.
    • ListView fix: codec encode-level + legacy tests; bug-test mdl-examples/bug-tests/listview-database-source-searchrefs.mdl; mx check 0 errors + a valid client chunk on a Deploy build.
    • TestMxCheck_DoctypeScripts/alter-page-insert-into passes on both engines against cached mxbuild 10.24.19 (9 lines gated) and 11.12.1 (full script), 0 errors.
    🤖 Generated with Claude Code

claude added 4 commits July 22, 2026 15:45
…eration

Investigating "SCSS edits don't show up in the running app" surfaced three
issues in the warm local loop — none an actual compiled-CSS cache:

1. Stale process silently adopted (the real time-sink). Nothing checked that
   the loop's ports were free before booting, and the readiness probes
   (StartServe.waitReady / runtime waitAdminReady) treat "the port answers" as
   "ready" — which a leftover mxbuild --serve/runtime satisfies. So a fresh
   `run --local` attached to the OLD process (its own child, unable to bind, was
   torn down by defer) and kept serving old output. Add checkTargetPortsFree:
   refuse to boot with an actionable message when :8080/:8090/:6543 already
   answer. Detect only, never kill — reaping someone's process is the user's
   call.

2. Theme source was watched by nothing. The --watch change signal was
   model-only (.mpr + mprcontents/), so editing theme/web/main.scss or
   themesource/<module>/web/*.scss triggered no rebuild even under --watch. Add
   themeSourceMTime and combine it with the model signal in sourceMTime; both
   are mtime-polling, so this is container-safe (unlike the rollup chokidar
   web-client watcher). A theme edit now rebuilds and hot-applies.

3. "Did my change take?" was unanswerable. watchAndApply already tracked a
   client-bundle generation but never surfaced it; log a monotonic build
   generation (boot is #1) on every apply.

The incremental theme step itself is fine — verified that one /build after an
SCSS content edit rewrites theme-cache/web/theme.compiled.css — so there is no
cache to clear; the "rm -rf theme-cache" ritual was a red herring.

Tests: TestCheckTargetPortsFree (free ports pass; an occupied port is named in
the refusal) and TestThemeSourceMTime_WatchesThemeAndThemesource (theme/ and
themesource/ edits advance the combined watch signal).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
…ss guidance

Document the outcome of the "SCSS cache" investigation across the two canonical
homes (docs-site page + synced skill) plus the dev symptom table:

- The --watch change signal now covers theme source (theme/, themesource/) as
  well as the model, and logs a build-generation counter.
- Editing SCSS needs a rebuild (--watch or a clean restart), never a cache
  clear — mxbuild --serve recompiles the theme on the next /build and picks up
  content changes, so `rm -rf theme-cache/ .mendix-cache/` is a red herring.
- "My edit didn't show up" is usually a stale serve/runtime still serving on
  the ports, not a cache: run --local now refuses to boot when the ports are
  taken, and the docs give the pgrep/kill/curl recovery and the "launch as the
  sole command, poll separately" guidance.
- fix-issue.md gets a symptom row mapping the whole class to runlocal.go.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
A page with a native LISTVIEW over a `database from` (XPath) datasource passed
`mx check` but crashed the Mendix browser client at load and redirected to
login:

  TypeError: Cannot read properties of undefined (reading 'length')
    at processResult
    at retrieveByXPath

The serialized `Forms$ListViewXPathSource` was missing the lists the client
reads `.length` of:

- Codec (default engine): `Forms$ListViewSearch` was emitted without its
  `SearchRefs` list. The codec encoder drops an empty, never-Set PartList on a
  fresh element unless the $Type is registered — `Forms$GridSortBar.SortItems`
  was registered, but `Forms$ListViewSearch` was not. Register
  RegisterTypeDefaults("Forms$ListViewSearch", {MandatoryLists: ["SearchRefs"]}).
- Legacy engine: emitted a bogus `Forms$ListViewSort` and a `Paths` key (the
  search list was renamed `SearchRefs` in Mendix 7.11.0), and no
  `Forms$GridSortBar` at all — so sorting was dropped too. Rewrite
  serializeListViewDataSource (and the empty-source fallback, now the shared
  emptyListViewXPathSource helper) to mirror the pluggable
  CustomWidgetXPathSource: GridSortBar/SortItems + ListViewSearch/SearchRefs +
  ForceFullObjects.

The pluggable Gallery/DataGrid2 database source was already correct and is
unchanged.

Verified: `mx check` = 0 errors and a Deploy build compiles the page to a valid
client chunk (working sort). Tests: TestListViewSourceToGen_SearchRefsEmitted
(codec, encode-level), TestSerializeListViewDataSource_Database +
TestEmptyListViewXPathSource_Shape (legacy). Repro
mdl-examples/bug-tests/listview-database-source-searchrefs.mdl.

Note: a minimal database-from ListView compiles to a valid client chunk when
search is off, so this is the confirmed serialization defect matching the crash
signature rather than a reproduced crash; validation against the reporter's app
is pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
… doctype

The nightly builds its shared source project with Mendix 10.24.19, but
alter-page-insert-into.mdl created AlterInto.Detail with `params: {...}` — a
page parameter, which requires Mendix 11.0.0+. On 10.x the executor rightly
refused ("create page with parameters requires Mendix 11.0.0+"), failing the
TestMxCheck_DoctypeScripts/alter-page-insert-into subtests on both engines.

Move the Detail page and its ALTER (the dataview-child INSERT INTO case) to the
end of the script, contiguous, under a single `-- @Version: 11.0+` gate so the
harness filters them out on 10.x. The two AlterInto.Home cases (fill an empty
container; append to a populated one) remain ungated, so INSERT INTO is still
exercised on 10.x.

Verified against both cached mxbuild versions via the integration harness:
- 10.24.19: both engines PASS, "skipped 9 version-gated lines", mx check 0 errors.
- 11.12.1: both engines PASS, full script runs, mx check 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXnEgoc2NQP1Y2TWMCMXC4
@ako
ako merged commit db1e22a into mendixlabs:main Jul 22, 2026
4 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