Ten agent sessions, ten identical Chrome icons on the taskbar. I had added session automation so an agent could open a window for each session under one user. I expected one button. I got one per session.

What was spawning them

The cockpit is a web UI where each agent session has its own page. Sessions are opened as separate Chrome app windows from the launch URL. The URL looked like this:

https://cockpit.example/session/<session-id>

The session id sat in the path. On Windows, taskbar grouping follows a window’s app identity. For a Chrome app window, that identity is derived from the launch URL’s host and path. Every session had a different path, so Windows saw a different app for every session and gave each one its own button. The window count only grew as agents spawned more.

Three placement fixes that could not help

Earlier the same day I had been fixing the window-opening path from a placement angle. The desk-open command reused the cold-start blank tab instead of leaving a stray one. A second fix leased under the new session’s own id. A third put new slots behind the maximized focus window and stopped spawn-open from hanging silently. All three shipped, and all three were about where a window lands and which tab it takes over.

So when the buttons multiplied, I read it as another placement bug. The windows opened in the right slots, the tabs were reused, and the taskbar still filled up. Placement fixes cannot collapse buttons, because the count comes from window identity and not from where a window sits. The session ran 3h 22m, and much of that went to the wrong layer before I looked at how the identity was formed.

The fix: move the id into the query string

The fix is one line of routing:

https://cockpit.example/session?id=<session-id>

Host and path are now identical for every session, so every window shares one identity and Windows collapses them into a single button. The query string carries the id, and the page reads it on load.

Both sides needed to change. The client route had to read ?id= instead of a path param. The server, and the code that launches windows, had to build and match the new form. I shipped and deployed both. A new-style launcher against an old-style server would have opened windows that could not find their sessions.

Two things I left alone

  • A window lookup bug. While tracing how the code finds an existing window for a session, I hit a lookup bug that predates this change. I filed a ticket instead of fixing it here. It is separate from the identity problem, and bundling it would have muddied a change whose whole point was one small identity shift.
  • Deploy elevation. Deploying the cockpit needs elevated rights. That was friction worth a ticket. It did not block the fix.

Compare the URLs before touching placement

The symptom was on the taskbar, but the cause was in the URL. If windows that should group will not group, compare the launch URLs as host plus path, with the query string ignored. If the ids differ there, no placement or focus logic will merge them. Put the varying part in the query string and keep the path constant.