LearnNewsExamplesServices
Frontmatter
id18721
titleA projection landing while the overflow menu opens closes the menu
stateClosed
labels
bugaitesting
assigneesneo-opus-ada
createdAtSep 15, 2026, 5:07 AM
updatedAtSep 15, 2026, 9:15 AM
githubUrlhttps://github.com/neomjs/neo/issues/18721
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtSep 15, 2026, 9:15 AM

A projection landing while the overflow menu opens closes the menu

neo-opus-ada
neo-opus-ada commented on Sep 15, 2026, 5:07 AM

This is the successor to #18348, which PR #18353 closed. #18348 left one question open, and this ticket answers it with a local reproduction.

Context

component/tab/OverflowAction.spec.mjs:162 (renders first, outside focus gating, with measured non-overlap and ordinary menu activation) failed the components job in 15 of the last 25 failed Engine Tests runs, from 2026-09-08 to 09-14. Five of those failures were on dev: 34228960926, 34253760041, 34355808406, 34400460345 and 34580274841. Every failure looks the same: the overflow menu opens, its first item resolves, and the click times out because the item "was detached from the DOM".

#18348 bound the item by id, so the arm now fails naming it. Its open question stayed open: does the menu re-render after it is shown?

The Problem

The failure reproduces locally in Playwright Chromium with Emulation.setCPUThrottlingRate at 6. The arm's own steps fail 4 of 20 runs and 5 of 30 runs. A plain open-and-click without the arm's layout reads fails 0 of 20.

A DOM mutation trail recorded identically on all 5 failures (ms from when the observer attached; the control's pointerdown lands at about 38):

ms mutation
~44 + tab header buttons 7 and 8
~89 + neo-menu-list-1, mounted with records 1 and 2
~110 one batch: + records 3, 4 and 5; − records 1 and 2; − header buttons 6, 7 and 8
~176 − neo-menu-list-1

Reading the trail against the source: at ~44, the restored header buttons match #project's recapture, which restores hidden buttons so it can measure them. At ~110, one batch applies a new split with three tabs hidden and rewrites the open menu's items. The menu closes about 65 ms later. A user who clicks the control while a projection's measurement is still in flight hits the same window; throttling only widens it.

The Architectural Reality

  • Overflow#queueOpenMenuProjection (src/tab/plugin/Overflow.mjs) parks a projection only while menuList.mounted is true, and #project calls it again at the mutation boundary, just before applySplit.
  • button.Base#toggleMenu sets menuList.hidden = false synchronously. mounted turns true only after the shown menu's vnode has been inserted. A projection whose getDomRect resolves between those two moments passes both checks.
  • Overflow#syncControl then writes menuList.items for the changed signature. Its own idempotence note says a rewrite rebuilds the dropdown and closes it mid-interaction.
  • #restoreOpenMenuPartition runs on the menu's mounted edge. It already handles part of this case: a recapture that made hidden headers visible while the menu was opening.

The Fix

This is a candidate until the reproduction confirms it. Park while the menu is open or opening (menuList && !menuList.hidden) instead of only while it is mounted. A projection that resolves after the click then parks, and drains on the menu's unmount edge as it does today.

Acceptance Criteria

  • A red-first arm, with no CPU throttling, shows that a projection resolving after toggleMenu shows the menu but before the menu mounts is parked. The open menu's items and the header partition stay untouched.
  • The CPU-throttled open-and-click reproduction above fails on dev and passes 60/60 with the fix.
  • A projection requested while the menu is open still drains once the menu closes. A projection requested while the menu is closed still applies immediately.
  • OverflowAction.spec.mjs passes in full.

Out of Scope

  • Header actions evicting tab buttons in narrow dock zones (#18693). That is the documented repartition, not this race.
  • When projections run, and the menu's item rewrite outside the opening window.

Related

#18348 (predecessor) · PR #18353 · #18693 (same surface, different mechanism) · PR #17626 (introduced the open-menu park) · PR #18722 (the fix)

Decision Record impact: none. Structure map: N/A. An existing plugin changes in place. Live latest-open sweep: checked the latest 20 open issues at 2026-09-15T03:05Z. No equivalent; #18693 is adjacent, as noted above. A2A in-flight claim sweep: checked the latest 30 messages in all read states. No claim covers the overflow plugin or this arm. Memory Core rationale sweep: no prior decision on the parking window. Own-assignment sweep: none of my open assignments covers this.

Origin Session ID: b9eefdf5-60e0-4156-860c-8cb4a628b8db

tobiu referenced in commit 3920d10 - "fix(tab): a projection landing while the overflow menu opens parks instead of rewriting it (#18721) (#18722) on Sep 15, 2026, 9:15 AM
tobiu closed this issue on Sep 15, 2026, 9:15 AM