Plugin pane buttons dropped when the desktop surface renders the same pane at two widths (ui_press handled: false)
Plugin pane buttons stop working when the desktop surface renders the same pane at two widths
Version: Claude Code 2.1.296, Claude desktop app (Code tab), macOS (Darwin 27.0.0)
Plugin: agents-panel 0.5.0 (a mod that draws a Pane with Button elements, each with a key)
What happens
In the desktop app, clicking buttons in a plugin's pane often does nothing. In our case the pane's ▶ buttons start agents, and the click is simply dropped: no run is recorded. I also see "unable to do task" errors after some launches, but have not tied that message to this cause.
Cause (reproduced headlessly)
When a surface renders the same Pane instance twice at different bodyColumns, the second ui_render gives its buttons new press handles and releases the handles from the first render. A ui_press that uses a handle from the first render comes back {handled: false}. The desktop app does draw the pane twice at different widths, so any press that lands on the first drawing is dropped.
This happens with one client_id drawing twice and with two different client_ids.
Repro
ui_render the same pane (component: 'Pane', instance_id: 'agents-panel', surface: 'desktop') at bodyColumns: 60, then at bodyColumns: 44, and then ui_press each button's handle:
same client, two widths | A handle 180981019 B handle 180981045
A presses its button: {'handled': False}
B presses its button: {'handled': True, 'element': 'fold:self'}
two clients, two widths | A handle 180981071 B handle 180981097
A presses its button: {'handled': False}
B presses its button: {'handled': True, 'element': 'fold:self'}
Pressing with a fresh render's handle always works. Only the older render's handle is dropped.
Expected
Pressing a button from either drawing of the pane is handled, or the app never keeps a drawing whose handles have been released.
Notes
- The plugin cannot fix this. It never sees the dropped press, because the engine answers
handled: falsebefore any hook runs. - The plugin's session file (
~/.claude/agents-panel/sessions/<id>.json) showsruns: []after a click, so the press never reaches the plugin.