Closed bug report

After 2.0.572 update, three threads' sessions share one hwnd, so raising one surfaces another thread's window

John Lauer · 1mo ago ·closed by John Lauer

Machine: AdomLapper (Windows), pup 2.0.572 (updated from 2.0.566 during the session on 2026-09-14), Adom Bridge 2.1.118.

What happened: thread "all-engineering agenda" asked pup to show its window. pup_raise_os_window {foregroundReason} returned ok, but the window that came to the front was another thread's window: session nsf-pages2 (owner "NSF"), showing the node talk page.

Why: pup_list_windows reports three different sessions, owned by three different threads, all with the SAME hwnd:

pup-wiki               owner pup-bridge              hwnd 2950842
all-engineering-agenda owner all-engineering agenda  hwnd 2950842
nsf-pages2             owner NSF                     hwnd 2950842

pup_list_tabs for all-engineering-agenda shows one active tab (the agenda doc), so pup itself treats it as its own window. The handle tagging is what is wrong: raising any of the three raises the NSF window, which breaks the window-ownership promise (one thread surfaced another thread's window).

Sequence that led here (all within ~15 min, same box):

  1. The agenda session's window disappeared; pup_rescan said the session was disconnected and its browser was gone.
  2. pup_open_window then timed out at ab's 60s budget while pup updated to 2.0.572.
  3. Next pup_open_window {foreground:true, foregroundReason} failed with ext_no_answer (40s).
  4. Retry returned ok, but nothing came to the front; pup_raise_os_window said no_window_handle.
  5. After pup_rescan ("All known sessions are live: []"), pup_raise_os_window returned ok and raised hwnd 2950842, the NSF window.

Also: desktop_list_windows on this box returned only 3 windows (Edge, Hydrogen, Windows Input Experience) and none of the pup windows, while the NSF pup window was the foreground window.

Expected: each session is tagged with its own OS window; a raise for one thread never surfaces another thread's window, and if pup is not sure which hwnd is right it should refuse rather than raise a guess.

1 Reply

John Lauer · 1mo ago

Fixed in 2.0.573 (insiders, 2026-09-14) and proven since. Root cause was the Rust port dropping the birth lock around the window set-diff, plus a handle resolver that handed the sole lane window to every asking session; with three threads opening at once all three claimed one hwnd, and raising any of them raised the last stamp's owner. 2.0.573 restored the lock, refuses any handle another session owns, filters births to the lane's own Chrome pids, and leaves a session bare rather than guess. Proof: five threads opened concurrently, five distinct hwnds, Windows reports five distinct AUMIDs and tiles; the concurrent N-threads-N-handles check is now scenario text in dev-skills/pup-window-targeting. Also since then: 2.0.585 keeps windows at z-bottom (ab's attention clear was lifting them, adom-bridge#199), 2.0.588 never takes a raised window back from the user, 2.0.590 fixes the worker stall that produced the ext_no_answer and 60 s timeouts in your sequence. Closing.

John Lauer closed this · 1mo ago

Log in to reply.