Uploaded image for project: 'XWiki Platform'
  1. XWiki Platform
  2. XWIKI-24857

Navigation Panel administration: dragging pages in or out of the tree sometimes has no effect on the tree

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • 14.1
    • Panels
    • None
    • Unknown

    Description

      Sometimes, when you open Administration > Look & Feel > Navigation Panel, the page tree on the left stops reacting to the configuration changes you make. Nothing indicates that something is wrong – the "Excluded Pages" panel on the right behaves normally, so the breakage only shows up in the tree, and only once you try to change something. Reloading the page usually makes it work again.

      What you can observe, all in the same broken state:

      • You drag the last remaining page from the tree into "Excluded Pages". The page is correctly added to the "Excluded Pages" list, but the tree goes completely blank instead of displaying "No pages found".
      • You drag a page from "Excluded Pages" back onto the tree. The page disappears from the "Excluded Pages" list – so the form now says it will be included – but it is not added back to the tree. The tree keeps showing its previous content, or "No pages found". Re-including a page looks impossible until you reload.
      • You untick "Top Level Extension Pages". The pages that filter was hiding are not put back into the tree.
      • The pin / unpin buttons are missing from the tree nodes, and pages that are already pinned are not displayed as pinned, so you cannot tell or change the pinned state.

      The practical impact is that the tree stops being a preview of the configuration: what you see while editing no longer matches what gets saved, and an administrator can save a navigation configuration they did not intend.

      Steps to reproduce

      This is a page-load race, so it does not reproduce on demand – it depends on whether the tree finishes loading before or after the section's own JavaScript. It is much more frequent in Firefox. Two ways to force it:

      1. Throttle the browser network (or slow the server) so the section's translations request, GET /rest/wikis/<wiki>/localization/translations, resolves after the tree's children request.
        Then go to the Navigation Panel section, drag a top level page into "Excluded Pages" and drag it back – it will not return to the tree.
      2. Deterministically, in the JSX of PanelsCode.NavigationConfigurationSheet: wrap everything from const $navigationTree = ... to the end of the require callback in a function and invoke it from a one-shot ready.jstree listener. Every run then reproduces the bug.
      const forceRaceTreeSetup = function() { /* ...original tail of the module... */ };
      const $forceRaceTree = $('.navigationPanelConfiguration .xtree');
      if ($forceRaceTree.jstree?.(true)?._data?.core?.ready) {
        forceRaceTreeSetup();
      } else {
        $forceRaceTree.one('ready.jstree', function() {
          setTimeout(forceRaceTreeSetup, 0);
        });
      }
      

      Technical cause

      PanelsCode.NavigationConfigurationSheet registers its jsTree listeners inside require(['jquery', 'xwiki-l10n!...', 'xwiki-meta', 'jquery-ui', 'xwiki-events-bridge'], ...), that is, after a REST round trip for the translations. The tree is initialized and loaded independently (xwiki-platform-tree-war/.../widgets/tree.js on DOM ready, then AJAX). Nothing synchronizes them, so the tree can fire ready.jstree / model.jstree / redraw.jstree before the sheet's listeners exist.

      The decisive one is ready.jstree, which is where the sheet declares the node types the tree root accepts. Without it, getChildren in tree.js leaves the root's validChildren at the value it inferred from the server response, and check_callback / canAcceptChild then silently rejects every create_node of the missing type:

      State when the page was loaded Inferred validChildren What gets silently rejected
      Tree contains pages ['document'] (or ['document', 'pagination']) the empty placeholder, so the tree renders blank
      All pages excluded ['empty'] every document node, so pages cannot be put back

      The missed model.jstree and redraw.jstree listeners account for the pinned marks and the missing pin buttons. The sheet already worked around a symptom of this race for the node template, but that mitigation is incomplete and its redraw(true) runs before the redraw.jstree listener is registered.

      Proposed fix

      • Set the root node data on the tree element itself ($navigationTree.data('root', ...)) as soon as the module runs, so the tree picks up the valid child node types when it loads the root and never infers them. This also prevents the types from being re-inferred when the root is refreshed.
      • Extract the bodies of the ready.jstree / model.jstree / redraw.jstree listeners into functions, and add a catch-up at the end of the module that applies them to an already loaded tree and then does a full redraw – after all listeners are registered.

      Versions

      The defect has been present since 10.5 (XWIKI-15260), which introduced the drag and drop configuration and registered the ready.jstree listener without handling the case where the tree is already ready. It only became realistically triggerable in 14.1, when XWIKI-14928 added the xwiki-l10n! dependency to the section's JavaScript: before that the module only waited for local scripts and practically always won the race against the tree's AJAX load, whereas now both sides make a server round trip. The pin related symptoms additionally require the manual ordering feature added in 16.x (XWIKI-14422), with the current pin action from 16.4.7 / 16.10.4 / 17.1 (XWIKI-23950).

      Related

      XWIKI-23126NavigationPanelAdministrationIT#navigationPanelAdministration has been failing on CI with exactly this cause: about 11% of 1167 runs over 60 days, Firefox only, in two signatures matching the table above:

      org.opentest4j.AssertionFailedError: expected: <[No pages found]> but was: <[]>
      org.opentest4j.AssertionFailedError: expected: <[Alice, Bob, D e%n+i/s, XWiki]> but was: <[No pages found]>
      

      The failure rate jumped from 3.4% to 21.7% on 2026-08-13 across all branches at once, which points at a browser image update shifting the race rather than at a code change. The test side wait added under XWIKI-23126 did not help – it only converted some assertion failures into timeouts. This CI flicker is therefore the product bug, not a test problem.

      Bug reproduced with and issue description written by Claude Opus 5 (1M context).

      Attachments

        Issue Links

          Activity

            People

              MichaelHamann Michael Hamann
              MichaelHamann Michael Hamann
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated: