Unity-Technologies/ml-agents · error · IndexOutOfRangeException

row was {row}, but must be between 0 and {maxBoardSize.Rows

Error message

row was {row}, but must be between 0 and {maxBoardSize.Rows - 1}.

What it means

Match3's Move.FromPositionAndDirection validates that the given row is within the board bounds (0 .. maxBoardSize.Rows-1) before creating a Move; out-of-range rows raise IndexOutOfRangeException with this message. It is a bounds check against the maximum supported BoardSize, not the current board necessarily.

Source

Thrown at com.unity.ml-agents/Runtime/Integrations/Match3/Move.cs:156

                    Column = 0;
                }
            }
        }

        /// <summary>
        /// Construct a Move from the row, column, direction, and board size.
        /// </summary>
        /// <param name="row">Row</param>
        /// <param name="col">Col</param>
        /// <param name="dir">Dir</param>
        /// <param name="maxBoardSize">Max board size</param>
        /// <returns>Corresponding `Move`.</returns>
        public static Move FromPositionAndDirection(int row, int col, Direction dir, BoardSize maxBoardSize)
        {
            // Check for out-of-bounds
            if (row < 0 || row >= maxBoardSize.Rows)
            {
                throw new IndexOutOfRangeException($"row was {row}, but must be between 0 and {maxBoardSize.Rows - 1}.");
            }

            if (col < 0 || col >= maxBoardSize.Columns)
            {
                throw new IndexOutOfRangeException($"col was {col}, but must be between 0 and {maxBoardSize.Columns - 1}.");
            }

            // Check moves that would go out of bounds e.g. col == 0 and dir == Left
            if (
                row == 0 && dir == Direction.Down ||
                row == maxBoardSize.Rows - 1 && dir == Direction.Up ||
                col == 0 && dir == Direction.Left ||
                col == maxBoardSize.Columns - 1 && dir == Direction.Right
            )
            {
                throw new IndexOutOfRangeException($"Cannot move cell at row={row} col={col} in Direction={dir}");
            }

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Clamp/validate row against board.MaxRows (or the actual board's Rows) before calling FromPositionAndDirection
  2. Only generate moves from valid cell coordinates (iterate board.Cells or use board validity checks)
  3. Use BoardSize values consistent with the actual board dimensions

Example fix

// before
var move = Move.FromPositionAndDirection(actionRow, actionCol, dir, board.MaxBoardSize);
// after
actionRow = Mathf.Clamp(actionRow, 0, board.Rows - 1);
var move = board.CheckMove(actionRow, actionCol, dir); // returns null if invalid
Defensive patterns

Strategy: validation

Validate before calling

bool CanPlace(int row, int col, BoardSize size) =>
    row >= 0 && row < size.Rows && col >= 0 && col < size.Columns;
// before calling: if (!CanPlace(row, col, board.MaxBoardSize)) skip/retry;

Type guard

bool IsValidRow(int row, BoardSize size) => row >= 0 && row < size.Rows;

Try / catch

try { var move = Move.FromPositionAndDirection(row, col, dir, board.MaxBoardSize); }
catch (IndexOutOfRangeException e) when (e.Message.StartsWith("row was"))
{ row = Mathf.Clamp(row, 0, board.MaxBoardSize.Rows - 1); }

Prevention

When it happens

Trigger: Calling Move.FromPositionAndDirection with row < 0 or row >= maxBoardSize.Rows — e.g. computing coordinates from an agent's action output without clamping, or passing a boardSize smaller than the actual board.

Common situations: Neural/heuristic agents emitting raw action values used directly as row coordinates; translating pixel or grid coordinates without accounting for row/column ordering; boards resized without updating maxBoardSize.

Related errors


AI-assisted analysis of Unity-Technologies/ml-agents@3ecb446f75 (2026-09-02). Data as JSON: /api/errors/5d8af2bb9938827f. Report an issue: GitHub.