Unity-Technologies/ml-agents · error · IndexOutOfRangeException

col was {col}, but must be between 0 and {maxBoardSize.Colum

Error message

col was {col}, but must be between 0 and {maxBoardSize.Columns - 1}.

What it means

Same bounds check as the row variant but for the column: Move.FromPositionAndDirection throws IndexOutOfRangeException when col is negative or >= maxBoardSize.Columns. The Move API requires the source cell to exist on the board before direction normalization.

Source

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

        /// <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}");
            }

            // Normalize - only consider Right and Up
            if (dir == Direction.Left)
            {
                dir = Direction.Right;
                col = col - 1;

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Validate/clamp col against board.Columns before constructing the move
  2. Verify argument order — FromPositionAndDirection takes (row, col, dir, maxBoardSize)
  3. Generate moves via board.CheckMove or iterate legal moves instead of constructing raw coordinates

Example fix

// before
var move = Move.FromPositionAndDirection(x, y, dir, board.MaxBoardSize); // x,y swapped
// after
var move = board.CheckMove(y, x, dir); // row=y, col=x, null-checked
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;
// validate col before: if (col < 0 || col >= board.MaxBoardSize.Columns) retry;

Type guard

bool IsValidCol(int col, BoardSize size) => col >= 0 && col < size.Columns;

Try / catch

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

Prevention

When it happens

Trigger: Calling Move.FromPositionAndDirection with col < 0 or col >= maxBoardSize.Columns — typically unvalidated agent action output or transposed row/col arguments.

Common situations: Passing (col, row) in the wrong order; agents emitting raw unclamped action indices; mismatch between the passed maxBoardSize and the real board size.

Related errors


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