Ten agent sessions, ten identical Chrome icons on the taskbar. We had added session automation so an agent could open a window for each session under one user. We expected one button. We got one per session.
What was spawning them
The agent control UI 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://dashboard.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 we had been fixing the window-opening path from a placement angle. The desk-open command now 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, we read it as another placement bug. That was the wrong call, and it cost us. The windows opened in the right slots, the tabs were reused, and the taskbar still filled up. We kept working the placement layer, and the session ran 3h 22m, much of it spent there. Placement fixes cannot collapse buttons, because the count comes from window identity and not from where a window sits. Only when we looked at how the identity was formed did the path show up.
The fix: move the id into the query string
The fix is one line of routing:
https://dashboard.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 had 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. We shipped and deployed both together, because a new-style launcher against an old-style server would have opened windows that could not find their sessions.
Two things we left alone
- A window lookup bug. While tracing how the code finds an existing window for a session, we hit a lookup bug that predates this change. We 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 agent control UI needs elevated rights. That was friction worth a ticket. It did not block the fix.
Compare the URLs first
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.
Here, every session had a different path, so Windows treated each as a separate app, and three placement fixes could not change that. Moving the id into the query string gave every window one identity.