Codex App: selected-text action toolbar is clipped to the width of short user-message bubbles

Open 💬 0 comments Opened Jul 31, 2026 by postmelee

What version of the Codex App are you using (From “About Codex” dialog)?

Codex App 26.721.41059
Build 5848
Bundle identifier: com.openai.codex

What subscription do you have?

ChatGPT Pro ($200/month)

What platform is your computer?

Darwin 25.5.0 arm64 arm

What issue are you seeing?

When text is selected inside a short, right-aligned user-message bubble, the selected-text action toolbar is horizontally clipped to approximately the width of that message bubble.

In the Korean locale, the toolbar should display these three applicable actions:

  • 작업에 추가 (the Add to chat/task action)
  • 더 자세히 (More details)
  • 사이드 채팅에 질문하기 (Ask in side chat)

Instead, selecting the complete short message “이렇게 떴어.” causes the toolbar to be reduced to a narrow region. Only the middle action, “더 자세히,” remains readable, while the actions on either side are clipped and cannot be used normally.

This is not caused by the application window being too narrow. In the same window and thread, selecting assistant-response text displays the complete three-action toolbar correctly.

The problem therefore appears to be specific to selected text inside a narrow user-message bubble rather than a general viewport-width issue.

Impact:

  • One or more contextual actions become visually inaccessible.
  • Users cannot reliably add selected user-message text back to the task or ask about it in a side chat.
  • The problem is especially noticeable for short messages and locales with longer translated action labels.
  • There is no ellipsis, horizontal scrolling, wrapping, or alternate access path indicating that the actions were intentionally collapsed.

What steps can reproduce the bug?

  1. Open Codex App on macOS.
  2. Use the Korean locale. Other locales may also be affected, but this reproduction uses Korean.
  3. Open an existing task or create a new one.
  4. Send or locate a short user message, for example:

~~~text
이렇게 떴어.
~~~

  1. Drag across the complete text to select it.
  2. Observe the contextual selected-text action toolbar displayed above the selection.

Actual result:

  • The toolbar is constrained to approximately the width of the short user-message bubble.
  • Only “더 자세히” is readable.
  • “작업에 추가” and “사이드 채팅에 질문하기” are clipped.

Control case:

  1. In the same thread and without resizing the window, select text in an assistant response.
  2. Observe that the complete toolbar is displayed correctly with all three actions.

No particular session state, token usage, or context-window usage appears to be required. This is a presentation/layout issue.

What is the expected behavior?

The selected-text toolbar should display all applicable actions completely regardless of the width of the selected user-message bubble.

The toolbar should remain anchored near the selection, but its collision boundary should be the actual thread viewport or application viewport—not the width of the message bubble containing the selected text.

If centering the toolbar over the selection would cross a real viewport boundary, the toolbar should shift horizontally while remaining near the selection.

On an exceptionally narrow application viewport, the toolbar should wrap, scroll, or expose an accessible overflow menu instead of silently clipping actions.

Additional information

Screenshots

<!-- Please edit the issue and drag the screenshot showing the user message before selection here. -->

  1. Short user message before selection.

<img width="1617" height="1061" alt="Image" src="https://github.com/user-attachments/assets/9774f91d-b53d-4e29-b7af-b1d90f1050ef" />

<!-- Please edit the issue and drag the screenshot showing the clipped toolbar here. -->

  1. Short user message selected, showing the clipped toolbar.

<img width="1617" height="1061" alt="Image" src="https://github.com/user-attachments/assets/4210e19e-38f5-4fc4-b7b8-0ac5aba6c6cd" />

<!-- Please edit the issue and drag the screenshot showing the complete assistant-text toolbar here. -->

  1. Assistant-response text selected in the same window, showing the complete toolbar.

<img width="1617" height="1061" alt="Image" src="https://github.com/user-attachments/assets/0fa8009c-4ac7-4d6f-8ee2-4b80830bcc82" />

Technical analysis

I inspected the packaged frontend bundle included with the currently installed Codex App 26.721.41059. The identifiers in the production bundle are minified and may not correspond directly to internal source names, but the relevant layout behavior remains visible.

An initially available extracted bundle was from the older 26.601.21317 build, so I did not rely on it for the final diagnosis. I confirmed the behavior and implementation pattern against the currently installed 26.721.41059 app bundle.

User-message bubble

The user-message bubble includes layout classes equivalent to:

~~~text
bg-token-foreground/5
max-w-[77%]
min-w-0
overflow-hidden
break-words
rounded-2xl
px-3
py-2
~~~

The important property is overflow-hidden.

For a short message, the bubble shrink-wraps to a narrow width. Its overflow clipping appears to be used for the rounded bubble presentation rather than to define a popup positioning boundary.

Selection-bound calculation

The selected-text overlay logic walks upward from the selected element and inspects the computed overflow styles of its ancestors.

Ancestors whose overflowX, overflowY, or shorthand overflow contains one of the following values are intersected into a common visible boundary:

~~~text
auto
clip
hidden
overlay
scroll
~~~

Conceptually, the calculation behaves like:

~~~ts
let bounds = {
left: 0,
right: window.innerWidth,
top: 0,
bottom: window.innerHeight,
};

for (const ancestor of selectionAncestors) {
const style = getComputedStyle(ancestor);

if (isClippingOverflow(style.overflowX)) {
bounds.left = Math.max(bounds.left, ancestorRect.left);
bounds.right = Math.min(bounds.right, ancestorRect.right);
}

if (isClippingOverflow(style.overflowY)) {
bounds.top = Math.max(bounds.top, ancestorRect.top);
bounds.bottom = Math.min(bounds.bottom, ancestorRect.bottom);
}
}
~~~

This boundary is returned as the overlay's horizontal bounds.

Because the user-message bubble has overflow-hidden, the bubble itself becomes one of those horizontal bounds. For a short message, the resulting horizontal range is approximately the narrow width of the bubble.

Toolbar sizing and clipping

The overlay then derives its maximum width from those bounds, approximately as follows:

~~~ts
const availableWidth =
horizontalBounds.right -
horizontalBounds.left -
16;

overlayStyle = {
left: selectionCenterX,
maxWidth: availableWidth,
top: selectionTop - 8,
transform:
"translateX(clamp(..., -50%, ...)) translateY(-100%)",
};
~~~

The toolbar container also uses layout behavior equivalent to:

~~~text
flex
w-fit
max-w-full
overflow-hidden
~~~

The combined result is:

  1. The narrow user-message bubble becomes the horizontal bounds.
  2. The outer overlay receives a max-width close to the bubble width.
  3. The inner toolbar is limited by max-w-full.
  4. overflow-hidden clips the actions that do not fit.
  5. Only part of the toolbar remains visible.

This matches the screenshots: a short user message produces a narrow toolbar showing only the center action, while assistant-response text—without the same narrow overflow-hidden ancestor—provides enough horizontal space for the complete toolbar.

Likely underlying design issue

The implementation appears to reuse the same bounds for two different purposes:

  1. Determining the visible portion of the selected text.
  2. Determining the collision boundary and maximum width of a portaled popup.

An overflow-hidden ancestor is relevant when deciding whether selected text is visible. However, it should not necessarily constrain a toolbar rendered through a portal outside that ancestor.

Here, the message bubble's decorative clipping boundary is incorrectly reused as the popup's available width.

Possible fix direction

A robust fix may be to maintain two separate boundaries:

~~~ts
selectionVisibilityBounds
overlayCollisionBounds
~~~

  • selectionVisibilityBounds can continue intersecting clipping ancestors so an anchor rectangle is chosen from the visible portion of the selection.
  • overlayCollisionBounds should be derived from the actual portal destination, thread scroll viewport, or window viewport.
  • A decorative overflow-hidden ancestor such as the user-message bubble should not limit the toolbar width after the toolbar has been portaled outside it.
  • The rendered toolbar width should be measured and shifted horizontally into the real collision boundary.
  • The toolbar should not be reduced to the selected text or message-bubble width.

A narrower fix could exclude the user-message bubble's overflow-hidden from horizontal overlay sizing, but separating selection visibility from overlay collision bounds would likely be safer for other portaled UI surfaces.

Suggested regression coverage

A regression test could render:

  • a right-aligned user-message bubble containing a very short string;
  • all three selected-text actions;
  • a locale with relatively long action labels, such as Korean;
  • a normal-width thread viewport.

After selecting the message, the test should assert that:

  • all three actions are present and visible;
  • the toolbar remains inside the thread or window viewport;
  • the toolbar is not constrained to the message-bubble width;
  • the same behavior works near both the left and right viewport edges.
Related issue

#25641 reports cases where the selected-response-text toolbar does not appear. This report is different: the toolbar appears, but its width and contents are clipped specifically for short user-message bubbles.

I can provide additional diagnostics, test other locales and window sizes, and validate a patched build if useful.

View original on GitHub ↗