Skip to content

MenuComplete throws ArgumentOutOfRangeException after shrinking an open completion menu #5218

Description

@Natsume-kkk

Prerequisites

Exception report

Captured from a deterministic reproduction with the unmodified PSReadLine 2.4.5 DLL on 2026-09-30. The text below is transcribed from the ConPTY screen snapshot; the only input was the synthetic completion prefix and navigation keys.

### Environment
PSReadLine: 2.4.5
PowerShell: 7.6.5
OS: Microsoft Windows 10.0.26200
BufferWidth: 118
BufferHeight: 34

Last 13 Keys:
z z r e s i z e Tab RightArrow RightArrow RightArrow RightArrow

### Exception
System.ArgumentOutOfRangeException: The value must be greater than or equal to zero and less than the console's buffer size in that dimension. (Parameter 'left')
Actual value was 120.
   at System.ConsolePal.SetCursorPosition(Int32 left, Int32 top)
   at Microsoft.PowerShell.Internal.VirtualTerminal.SetCursorPosition(Int32 left, Int32 top)
   at Microsoft.PowerShell.PSConsoleReadLine.Menu.UpdateMenuSelection(Int32 selectedItem, Boolean select, Boolean showTooltips, String toolTipColor)
   at Microsoft.PowerShell.PSConsoleReadLine.MenuCompleteImpl(Menu menu, CommandCompletion completions)
   at Microsoft.PowerShell.PSConsoleReadLine.PossibleCompletionsImpl(CommandCompletion completions, Boolean menuSelect)
   at Microsoft.PowerShell.PSConsoleReadLine.CompleteImpl(Boolean menuSelect)
   at Microsoft.PowerShell.PSConsoleReadLine.MenuComplete(Nullable`1 key, Object arg)
   at Microsoft.PowerShell.PSConsoleReadLine.ProcessOneKey(PSKeyInfo key, Dictionary`2 dispatchTable, Boolean ignoreIfNoAction, Object arg)
   at Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   at Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics, CancellationToken cancellationToken, Nullable`1 lastRunStatus)

Screenshot

N/A. The automated ConPTY reproduction captured text rather than a GUI screenshot. Before resizing, the 25 candidates formed five columns; after shrinking, navigation attempted to use the fifth column at offset 120, outside the new 118-column buffer.

Environment data

The version, OS and buffer dimensions above are from the failing session's exception report. The host was PowerShell ConsoleHost in a Windows ConPTY terminal (Unison), started with -NoProfile; Tab was bound to MenuComplete. History saving was disabled and candidates were synthetic functions, with no user profile, CLI extension or external completer involved.

Initial buffer: 160 columns x 34 rows.
Resized buffer: 118 columns x 34 rows.

The original real-world trigger was moving the terminal from a 100% scaling monitor to a 150% scaling monitor while the completion menu was open. A deterministic ResizePseudoConsole width change reproduces the same left = 120 exception without requiring a second monitor. I have not independently reproduced this in Windows Terminal, and a full dual-monitor GUI retest of the local fix is still pending.

Steps to reproduce

  1. Start pwsh -NoLogo -NoProfile with the official, unmodified PSReadLine 2.4.5 module in a 160-column, 34-row terminal.

  2. Set up the same 25 synthetic completion candidates and Tab binding:

    Import-Module PSReadLine -RequiredVersion 2.4.5
    Set-PSReadLineOption -EditMode Windows -HistorySaveStyle SaveNothing
    Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
    function global:prompt { 'RESIZE> ' }
    1..25 | ForEach-Object {
        $name = 'zzresize' + $_.ToString('00') + 'abcdefghijklmnopqr'
        Set-Item -Path ('function:global:' + $name) -Value { }
    }
  3. Type zzresize and press Tab. Keep the completion menu open.

  4. Shrink the terminal to 118 columns, keeping 34 rows, without dismissing the menu. In the automated reproduction this is a ConPTY resize from (160, 34) to (118, 34), followed by a 300 ms wait.

  5. Press RightArrow four times. PSReadLine reports the exception above.

Expected behavior

Recalculate and redraw the active completion menu for the new buffer width before navigating. Preserve the selected completion and input when possible. If the new dimensions cannot accommodate the menu, cancel it safely rather than addressing an invalid cursor position.

Actual behavior

The menu keeps its original layout. Each candidate is 28 cells wide, giving a cached ColumnWidth of 30, five columns and five rows at width 160. Moving to the fifth column then requests left = 30 * 4 = 120, although the current buffer only has columns 0 through 117. The completion menu throws ArgumentOutOfRangeException and its display/input can become mixed after reflow.

Source analysis and local fix evidence

A local downstream patch against v2.4.5 detects dimension changes after the menu's key read, recalculates the active and filtered-stack menu layouts, and refreshes their drawing positions together with the prompt. It cancels safely when there is insufficient space and avoids executing input when an Enter key only belonged to a canceled completion menu.

Real ConPTY regression checks with that patch passed under PowerShell 7.6.5 and Windows PowerShell 5.1: repeated width/height changes, selected candidate and input preservation, filtering followed by Backspace, Escape, accepting with Enter, insufficient-space cancellation, and reopening the menu. These are local downstream results, not an upstream fix or a completed dual-monitor GUI verification.

Related reports checked

#4187 also reports Menu.UpdateMenuSelection, but describes a top = 27 error at a fixed width rather than a reproducible cached-column failure after shrinking. #3637 concerns the input/prompt anchor after resizing. I did not find an existing report with this deterministic 160 -> 118 active-menu reproduction; please link or consolidate this issue if it shares the same root cause with another report.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-Triage 🔍It's a new issue that core contributor team needs to triage.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions