AvaloniaUI/Avalonia · error · ArgumentOutOfRangeException

Only Next, Previous, Up, Down, Left and Right directions are

Error message

Only Next, Previous, Up, Down, Left and Right directions are supported

What it means

FocusManager directional navigation (Move with XYFocus) only accepts the spatial/sequential directions Next, Previous, Up, Down, Left, Right. Other NavigationDirection values (e.g. First, Last, PageDown, Tab) are meaningless for XY directional focus, so ValidateDirection throws ArgumentOutOfRangeException.

Source

Thrown at src/Avalonia.Base/Input/FocusManager.cs:365

            ValidateDirection(direction);

            var focusOptions = ToFocusOptions(options, false);
            var result = FindNextFocus(options?.FocusedElement ?? Current, direction, focusOptions);
            _reusableFocusOptions = focusOptions;
            return result;
        }

        private static void ValidateDirection(NavigationDirection direction)
        {
            if (direction is not (
                NavigationDirection.Next or
                NavigationDirection.Previous or
                NavigationDirection.Up or
                NavigationDirection.Down or
                NavigationDirection.Left or
                NavigationDirection.Right))
            {
                throw new ArgumentOutOfRangeException(
                    nameof(direction),
                    direction,
                    $"Only {nameof(NavigationDirection.Next)}, {nameof(NavigationDirection.Previous)}, " +
                    $"{nameof(NavigationDirection.Up)}, {nameof(NavigationDirection.Down)}," +
                    $" {nameof(NavigationDirection.Left)} and {nameof(NavigationDirection.Right)} directions are supported");
            }
        }

        private XYFocusOptions ToFocusOptions(FindNextElementOptions? options, bool updateManifold)
        {
            // XYFocus only uses the options and never modifies them; we can cache and reset them between calls.
            var focusOptions = _reusableFocusOptions;
            _reusableFocusOptions = null;

            if (focusOptions is null)
                focusOptions = new XYFocusOptions();
            else
                focusOptions.Reset();

View on GitHub (pinned to 11c5427268)

Solutions

  1. Pass only Next/Previous/Up/Down/Left/Right to the directional Move overload.
  2. Use the tab-based Move path (or GetNextTab/GetPrevTab) for Tab/First/Last semantics.
  3. Branch on the direction: spatial vs sequential APIs differ.

Example fix

// before:
FocusManager.Instance?.Move(NavigationDirection.First); // throws in XY path

// after:
FocusManager.Instance?.Move(NavigationDirection.Next); // valid for directional
// or use tab navigation APIs for First/Last.
Defensive patterns

Strategy: validation

Validate before calling

if (direction is not (NavigationDirection.Next or NavigationDirection.Previous or
    NavigationDirection.Up or NavigationDirection.Down or
    NavigationDirection.Left or NavigationDirection.Right))
    throw new ArgumentOutOfRangeException(nameof(direction));
FocusManager.Instance?.Move(direction);

Type guard

static bool IsDirectional(NavigationDirection d) => d is NavigationDirection.Next or NavigationDirection.Previous or NavigationDirection.Up or NavigationDirection.Down or NavigationDirection.Left or NavigationDirection.Right;

Prevention

When it happens

Trigger: Calling `FocusManager.Instance.Move(NavigationDirection.First)` or any non-spatial direction through the code path that invokes ValidateDirection (the directional/XYFocus path).

Common situations: Reusing a NavigationDirection variable for both tab and directional navigation. Passing a UI-driven direction (PageDown/First) into the directional Move API.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/a8ea3a1e5875fccd. Report an issue: GitHub.