From 63db689ab75c6ba8fa26e36617eebc44d3bbff50 Mon Sep 17 00:00:00 2001 From: Ben Potter Date: Tue, 5 May 2026 08:05:11 -0500 Subject: [PATCH] fix(site/src/pages/AgentsPage): cap queued messages list height so chat scroll keeps working (#24950) Linear: [CODAGT-313](https://linear.app/codercom/issue/CODAGT-313/unable-to-scroll-long-queued-messages-in-coder-agents) ## Summary When many messages are queued in the agent chat, the chat history becomes unscrollable: mouse wheel and scrollbar drag both stop responding. The input wrapper in `AgentChatPageView.tsx:496` is `shrink-0 overflow-y-auto` with **no `max-height`**, so `overflow-y-auto` is a no-op and the section grows unbounded as `QueuedMessagesList` adds rows. Its sibling `ChatScrollContainer` is `flex-1 min-h-0`, so it absorbs the shrinkage and `clientHeight` collapses to 0. The chat list is then a zero-height viewport with nothing to scroll. Measured against the actual `AgentChatPageView` rendered in Storybook with 20 queued messages (1280x800): | | scroll-container `clientHeight` | input wrapper height | scrollable? | |---|---:|---:|---| | 0 queued | 502 px | 270 px | yes | | 20 queued, `main` | **0 px** | 1182 px | **no** | | 20 queued, this PR | 258 px | 502 px | yes | ## Demo ![scroll fix side-by-side](https://raw.githubusercontent.com/coder/coder/bpmct/codagt-313-assets/scroll-fix-side-by-side.gif) Left (`main`): wheel-up does nothing because the chat scroll container has been crushed to zero height. Right (this PR): the queued list scrolls inside its own pane and the chat history scrolls normally. Recording is `AgentChatPageView` rendered through Storybook with the production component source. The same gesture (wheel-up over the chat history, then wheel-down over the queued list) is applied to both sides. Source for the recording is in `bpmct/codagt-313-assets`. ## Change ```diff -
+ // Cap the queue at ~40% of the small viewport so a long queue + // does not push the chat history's scroll container down to + // zero height (CODAGT-313). The list scrolls inside its own pane. +
``` ## Why this spot, not the outer wrapper The composer textarea already self-caps at `max-h-[50vh]` in `ChatMessageInput.tsx:688`, so the only unbounded growth source in the input section is the queued list. Capping the list keeps the constraint colocated with the component that owns it, and any future consumer of `QueuedMessagesList` is automatically safe. `40svh` (small viewport height) so the queue doesn't fight with the iOS keyboard once it appears, matching the `h-dvh` decision in #24848. --- *Generated by Coder Agents.* --- .../src/pages/AgentsPage/components/QueuedMessagesList.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/site/src/pages/AgentsPage/components/QueuedMessagesList.tsx b/site/src/pages/AgentsPage/components/QueuedMessagesList.tsx index 43557bd109..acce523f4d 100644 --- a/site/src/pages/AgentsPage/components/QueuedMessagesList.tsx +++ b/site/src/pages/AgentsPage/components/QueuedMessagesList.tsx @@ -170,7 +170,12 @@ export const QueuedMessagesList: FC = ({ const isBusy = busyItem !== null; return ( -
+
{visibleItems.map((item, index) => { const isEditing = item.id === editingMessageID; const isFirst = index === 0;