Skip to content

fix(check): resolve the pages and flows a navigation or menu document names - #1570

Merged
ako merged 1 commit into
mendixlabs:mainfrom
stagknee:fix/navigation-target-not-found
Oct 20, 2026
Merged

ako merged 1 commit into
mendixlabs:mainfrom
stagknee:fix/navigation-target-not-found

Conversation

@stagknee

Copy link
Copy Markdown
Contributor

Closes #1569.

What it fixes

A navigation profile, or a create menu document, whose home page, role home page, login or not-found page, or menu-item page, microflow or nanoflow doesn't exist passed check -p and was written by exec. Only mx check reported it (CE1613).

navigation Responsive has reference errors:
  - home page: page not found: Shop.NoSuchHome
  - menu item 'G' > 'Bogus': page not found: Shop.NoSuchPage

How

  • navigationTargets (new, validate_navigation_targets.go) lists every target of an AlterNavigationStmt or CreateMenuStmt:

    • the home page or flow, per profile and per role;
    • the login and not-found pages;
    • menu items at any depth, for show page, call microflow and call nanoflow, and for create object (the entity and the page).

    It reads both syntaxes: Page/Microflow on an item when no Action is set. sign out and open link have no target.

  • Resolution uses the same lookups as the existing show page / call microflow checks, plus the script's own definitions, with the same wording ("page not found: X").

  • check -p runs it in validateProgramWithWarnings, so exec's pre-flight gets it too. The handlers (execAlterNavigation, execCreateMenu) also run it first, before anything is read or written, so exec --no-check is covered and a stated menu is never half-replaced. Only the clauses the statement states are checked, which fits the Navigation: an undefined glyph kills mxbuild with no error file, a partial create or modify navigation resets the menu #1522 rule that an omitted clause keeps its stored value.

  • A target the script creates further down follows the rule from Describe emits catalog order; exec and check refuse forward and cross-module references, so mutual recursion cannot be created #1405 for flow calls.

    • In a run that rolls back (plain exec, and check), it resolves. That shape works on main today: exec stores it by name and mx check reports 0 errors.
    • exec --continue-on-error, the REPL and -c refuse it up front ("references page X before it is created … this run cannot be rolled back"). That is new behaviour for those modes only.
  • When a backend returns an empty listing for a document kind, that kind is not checked, as in validateForwardDefRefs.

  • Also included: the check-syntax skill's references-resolved.md, a CHANGELOG entry (Fixed), a finding in findings/mdl-executor/, and mdl-examples/bug-tests/1569-navigation-target-not-found.mdl. The latter is a positive script; the negative cases need a project, so they're in the Go tests.

Evidence

  • Tests: 25 tests and subtests in validate_navigation_targets_test.go, covering:

    • both syntaxes, top level and nested groups;
    • the home page, role home, login and not-found pages, and microflow and nanoflow items;
    • a target created in the same script, and a System page;
    • exec refusing with the stored profile unchanged, --no-check, and forward references per run mode.
  • Control run: against main, 9 tests fail and 4 controls pass (existing targets, a target created earlier, a valid navigation written, a navigation written before its page). All pass with the fix.

  • Real run (Mendix 11.12.5 scratch app):

    v0.26.0 / v0.27.0 this branch
    bogus navigation (old form), check -p Check passed! reference errors listed
    same, exec profile written; mx check: 4 × CE1613 refused, nothing written; stored profile unchanged
    bogus navigation (mdl 1 form) same gap; mx check: 3 × CE1613 refused the same way
    valid navigation (existing pages, a Marketplace page, a page created in the same script) ok ok; mx check 0 errors
    new module + folders + navigation in one script ok ok; mx check 0 errors
  • Windows: go test ./mdl/executor/ shows the same 28 pre-existing failures as main (the sorted lists are identical). go vet and gofmt are clean.

  • Linux (golang:1.26.6-bookworm, ANTLR 4.13.2): make grammar build test check-mdl check-findings check-conformance check-migration-reference lint-go all pass, on the branch before its rebase onto Sync ako/mxcli: Business Events channel identity, describe/write round-trip fixes, more check coverage #1564. After the rebase there were no conflicts; go vet is clean and the navigation and menu executor tests pass.

Not covered

sync entities in an offline profile's block are entity references, and I haven't verified them against mx check, because a native profile can't be created from MDL.

🤖 Generated with Claude Code

… names (mendixlabs#1569)

A navigation profile points at documents in six places: the home page (and one
per user role), a home flow, the login page, the not-found page and every menu
item at any depth. A standalone menu document carries the same menu items.
Nothing resolved any of them, so `check -p` said "Check passed!", `exec` wrote
the profile, and only `mx check` objected (CE1613 "The selected page ... no
longer exists.", once for the home page and once per menu item). CREATE OR
REPLACE NAVIGATION rewrites the whole profile, and the menu builder stores a
target by name and never fails on it.

check -p now reports each unresolved target with the profile or menu document,
the menu item path and the missing name, using the lookups every other page,
microflow, nanoflow and entity reference is resolved with. exec runs the same
check in the handler before it reads or writes anything, so `exec --no-check`
is covered too. A menu document stored as excluded only warns.

A target the script creates resolves. One created further down also resolves in
a run that rolls back (plain exec, check), as a call to a flow created further
down does (mendixlabs#1405): upstream accepts a navigation written before its pages and
mx check reports 0 errors for it, so refusing it would break a working script.
exec --continue-on-error, the REPL and -c cannot roll back and refuse it, from
validateForwardDefRefs.

Measured on a Mendix 11.12.5 app: 4 x CE1613 before for the reported script,
refused by check -p and exec after, and a valid navigation (existing pages, a
Marketplace-module page, a page created in the same script) still passes check
and exec with 0 errors from mx check.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • Thorough test coverage: 500-line test file covers both syntaxes, all target types (home page/role home/login/not-found/menu items), forward references, script-created targets, and various exec modes (--continue-on-error, REPL, -c)
  • Proper integration: Validation is wired through the full pipeline - added to validateProgramWithWarnings (for check -p) and executor handlers (for exec), with proper handling of rollback semantics
  • Correct error messaging: Uses same wording as existing validations ("page not found: X") and includes full menu item path in errors (e.g., "menu item 'Admin' > 'Users'")
  • Handles edge cases:
    • Native profiles (special handling for home microflow stored as nanoflow)
    • Excluded documents (skipped validation, like excluded pages)
    • Forward references (respected based on rollback capability)
    • Both syntax variants (deprecated and mdl 1)
  • Documentation updates:
    • CHANGELOG entry
    • Updated references-resolved.md skill
    • Positive test case in mdl-examples/bug-tests/
    • New finding recorded in .claude/skills/fix-issue/findings/
  • Follows existing patterns: Mirrors validateForwardDefRefs approach for definition-order validation and forward reference handling

Recommendation

The pull request fully addresses issue #1569 by adding validation for navigation and menu targets before they are written to the model. It is thoroughly tested, properly integrated, and follows established project patterns. The fix ensures that check -p and exec now catch reference errors that were previously only reported by mx check (CE1613), preventing invalid configurations from being written to the model.

Approve the pull request.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

ako pushed a commit to ako/mxcli that referenced this pull request Oct 19, 2026
mendixlabs#1570 makes exec refuse a navigation target it cannot find,
and the doctype example named the login page Administration.login. The page
is Administration.Login, as everywhere else in the repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
ako pushed a commit to ako/mxcli that referenced this pull request Oct 19, 2026
mendixlabs#1570 resolved the login page like the home and not-found
pages. The sign-in page may be the theme's static login.html rather than a
page document, so a login page the project does not have is not a dangling
reference, and mx check accepts it: the doctype navigation example names
Administration.login, which the test project does not have, and builds
clean. The check refused it.

The login page is no longer a target. A new test pairs a login page outside
the project (accepted) with a missing not-found page (still refused) as its
control, and the "login page" case leaves the every-kind table. The
navigation example goes back to main's version (undoing b43f1d7 and
2f9876b), so it now also covers a login page outside the project.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
ako added a commit to ako/mxcli that referenced this pull request Oct 19, 2026
Integrate wave 1 of the upstream PRs (mendixlabs/mxcli mendixlabs#1574 mendixlabs#1575 mendixlabs#1572 mendixlabs#1570 mendixlabs#1563 mendixlabs#1561 mendixlabs#1568 mendixlabs#1566 #1368), with review follow-ups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
@ako
ako merged commit 6a969e3 into mendixlabs:main Oct 20, 2026
11 of 13 checks passed
ako pushed a commit that referenced this pull request Oct 20, 2026
…check

Review note on #1570: the len(known) == 0 guard reads like a
gap. It is the price of not turning a failed read into a false "not found".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
ako added a commit that referenced this pull request Oct 20, 2026
Sync ako/mxcli: integrate nine contributor PRs (#1574 #1575 #1572 #1570 #1563 #1561 #1568 #1566 #1368) with review follow-ups
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.

check -p and exec accept a navigation profile or menu whose home page or menu-item page/microflow does not exist

2 participants