tui-cs/Terminal.Gui · error · ArgumentOutOfRangeException

value

Error message

value

What it means

Thrown by LinearSelectorT's selected-index logic (ArgumentOutOfRange, param 'value') when the requested index is null in a context requiring a value, or < 0, or >= Options.Count. The setter first syncs the underlying _value from Options[value].Data, so an out-of-range index cannot be mapped. Note the prior branch handles the 'no options' case by clearing selection rather than throwing.

Source

Thrown at Terminal.Gui/Views/LinearRange/LinearSelectorT.cs:117

        get => SelectedIndices.Count > 0 ? SelectedIndices [0] : null;
        set
        {
            if (value is null)
            {
                if (!AllowEmpty)
                {
                    return;
                }

                _value = default;
                ApplySelectedIndices ([]);

                return;
            }

            if (Options is null || value < 0 || value >= Options.Count)
            {
                throw new ArgumentOutOfRangeException (nameof (value));
            }

            // Sync indices first so SelectedIndex can select an option whose Data equals the current
            // _value (e.g. selecting option 0 in a value-type selector where _value is already
            // default(int)=0 — Value setter would short-circuit on equality, leaving SelectedIndex null).
            T? newValue = Options [value.Value].Data;
            T? current = _value;
            bool valueChanged = !EqualityComparer<T?>.Default.Equals (current, newValue);

            if (valueChanged && RaiseValueChanging (current, newValue))
            {
                return;
            }

            _value = newValue;
            ApplySelectedIndices ([value.Value]);

            if (valueChanged)

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Re-clamp against the current Options.Count before assigning: selector.SelectedIndex = Options.Count > 0 ? Math.Clamp(idx, 0, Options.Count - 1) : null;
  2. Populate Options before setting the selected index.
  3. Treat a -1 from IndexOf as 'no selection' (assign null) rather than passing it through.

Example fix

// before
selector.SelectedIndex = currentOptions.IndexOf(match); // -1 -> throws 166

// after
int idx = currentOptions.IndexOf(match);
selector.SelectedIndex = idx >= 0 ? idx : null;
Defensive patterns

Strategy: validation

Validate before calling

int idx = currentOptions.IndexOf(match);
selector.SelectedIndex = idx >= 0 && idx < currentOptions.Count ? idx : null;

Type guard

static bool IsValidIndex(int? i, int count) => !i.HasValue || (i >= 0 && i < count);

Prevention

When it happens

Trigger: Setting SelectedIndex to a value computed from a stale Options list (list shrunk after the index was captured); setting it before Options is populated; arithmetic that yields -1 (e.g. .IndexOf returning -1) piped straight in.

Common situations: Reactive binding that updates selection before the options collection arrives; filtering Options down and forgetting to re-clamp the selection; index from a search/match that returned -1.

Related errors


AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13). Data as JSON: /api/errors/b5b55361b131891f. Report an issue: GitHub.