Files
kandev/docs/specs/ui/message-metadata-overflow.md
T

3.5 KiB

status, created, owner
status created owner
shipped 2026-08-14 kandev

Message metadata dialog scroll containment

Why

The chat message "Message Metadata" dialog (MessageDebugDialog in apps/web/components/task/chat/messages/message-actions.tsx) renders up to ten debug fields, the last of which is turn_metadata. Turns persist a large runtime_config_snapshot (baseline plus a config_options array), so the combined entries can easily exceed the dialog's max-h-[85vh] cap.

The dialog clips instead of scrolling. DialogContent gets max-h-[85vh] overflow-hidden, and its entries container (div.grid.gap-3.overflow-auto.pr-1) is a grid item of the dialog's base grid layout with no height constraint: CSS grid auto-rows grow to content height, so the container's own height equals its content height and its overflow-auto never engages. turn_metadata, being the last field, is pushed entirely below the visible area. The result is JSON clipped mid-content with no scrollbar anywhere, exactly as reported.

What

  • The message metadata dialog SHALL keep every entry reachable: when the entries exceed the dialog's available height, the entries area scrolls.
  • The dialog SHALL use the repo's established scrollable-dialog pattern (github-app-policy-dialog, jira-ticket-dialog): DialogContent becomes a flex column (flex max-h-[85vh] flex-col overflow-hidden), the DialogHeader is shrink-0, and the entries container becomes a height-constrained flex child (min-h-0 flex-1) so its existing overflow-auto engages.
  • The title and the dialog's close button SHALL remain visible while the entries area scrolls.
  • Individual JSON value boxes keep their existing max-h-[48vh] overflow-auto internal scrolling; that per-field cap is unchanged.
  • No change to entry content, ordering, keys, or data.

Scenarios

  • GIVEN a message whose debug entries (including a large turn_metadata) exceed the dialog's max-h-[85vh], WHEN the user opens the Message Metadata dialog, THEN the entries area scrolls and turn_metadata is reachable.
  • GIVEN the entries area is scrolled to the bottom, WHEN the user reads the last field, THEN turn_metadata is fully visible inside the dialog and the dialog's title and close button remain on screen.
  • GIVEN a short metadata set that fits inside the dialog, WHEN the user opens the dialog, THEN no scrollbar appears and the layout is unchanged from today.
  • GIVEN the dialog is open, WHEN the user presses Escape or clicks the close button, THEN the dialog closes as before.

Out of scope

  • Changing what metadata is captured, how it is ordered, or the per-field max-h-[48vh] cap.
  • Restyling the scrollbar or changing other dialogs' scroll behavior.
  • Altering the dialog's trigger, i18n strings, or accessible names.

Failure modes

  • If the dialog container keeps display: grid semantics (e.g. the merged class list regresses to the base grid), the entries container cannot be height-constrained and the clipping returns; the E2E regression asserts the entries area actually scrolls, so it fails on that regression.
  • If min-h-0 is dropped from the entries container, the flex child's min-height: auto prevents it from shrinking below content and clipping returns; the E2E scroll assertion catches this too.
  • A viewport shorter than the smallest single field set must still show the header and at least the top entries; the flex-column layout preserves the header regardless of remaining space.