Skip to content

truncateMiddle returns a string longer than maxLength when maxLength is 1 or 2 #37458

Description

@VINODvoid

Description

truncateMiddle in packages/tui/src/util/locale.ts returns a string longer than maxLength when maxLength is 1 or 2:

truncateMiddle("abcdefghij", 1) -> "…abcdefghij"   (11 chars, asked for 1)
truncateMiddle("abcdefghij", 2) -> "a…abcdefghij"  (12 chars, asked for 2)

The last line is:

return str.slice(0, keepStart) + ellipsis + str.slice(-keepEnd)

keepEnd is Math.floor((maxLength - 1) / 2), which is 0 when maxLength is 1 or 2. str.slice(-0) is str.slice(0) — the whole string — so instead of truncating, the function returns the entire input with an ellipsis attached. maxLength >= 3 is unaffected, which is why this hasn't shown up before.

This is reachable from the TUI. packages/tui/src/ui/dialog-select.tsx:701:

Locale.truncateMiddle(detail, Math.max(1, Math.min(76, dimensions().width - 12)))

The Math.max(1, ...) guard is there to handle narrow terminals, but it clamps to exactly the broken value. Running that expression against a 39-char detail string:

terminal width=13 -> maxLength=1 -> result is 40 chars  (overflows)
terminal width=14 -> maxLength=2 -> result is 41 chars  (overflows)
terminal width=15 -> maxLength=3 -> result is  3 chars  (correct)

So below ~15 columns the detail line renders the full untruncated string and overflows the layout it was meant to fit. packages/opencode/src/cli/cmd/run/splash.ts:203 uses the same Math.max(1, ...) shape.

Same root cause as #37368, but a different function — #37369 fixes truncateLeft and doesn't touch this one.

Note: packages/core/src/util/path.ts:31 has an independent copy of truncateMiddle with the same -0 defect. It currently has no callers, so it isn't user-visible. Happy to fix it in the same PR or leave it out.

Steps to reproduce

  1. Resize the terminal to 14 columns or fewer
  2. Open a select dialog that renders a detail line (e.g. the session or model picker) with a detail string longer than the width
  3. The detail renders in full instead of truncated, overflowing the dialog

Operating System

Linux

Terminal

ghostty
kitty

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions