{"record":{"id":"5d8af2bb9938827f","repo":"Unity-Technologies/ml-agents","slug":"row-was-row-but-must-be-between-0-and-maxboard","errorCode":null,"errorMessage":"row was {row}, but must be between 0 and {maxBoardSize.Rows - 1}.","messagePattern":"row was (.+?), but must be between 0 and (.+?)\\.","errorType":"exception","errorClass":"IndexOutOfRangeException","httpStatus":null,"severity":"error","filePath":"com.unity.ml-agents/Runtime/Integrations/Match3/Move.cs","lineNumber":156,"sourceCode":"                    Column = 0;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Construct a Move from the row, column, direction, and board size.\n        /// </summary>\n        /// <param name=\"row\">Row</param>\n        /// <param name=\"col\">Col</param>\n        /// <param name=\"dir\">Dir</param>\n        /// <param name=\"maxBoardSize\">Max board size</param>\n        /// <returns>Corresponding `Move`.</returns>\n        public static Move FromPositionAndDirection(int row, int col, Direction dir, BoardSize maxBoardSize)\n        {\n            // Check for out-of-bounds\n            if (row < 0 || row >= maxBoardSize.Rows)\n            {\n                throw new IndexOutOfRangeException($\"row was {row}, but must be between 0 and {maxBoardSize.Rows - 1}.\");\n            }\n\n            if (col < 0 || col >= maxBoardSize.Columns)\n            {\n                throw new IndexOutOfRangeException($\"col was {col}, but must be between 0 and {maxBoardSize.Columns - 1}.\");\n            }\n\n            // Check moves that would go out of bounds e.g. col == 0 and dir == Left\n            if (\n                row == 0 && dir == Direction.Down ||\n                row == maxBoardSize.Rows - 1 && dir == Direction.Up ||\n                col == 0 && dir == Direction.Left ||\n                col == maxBoardSize.Columns - 1 && dir == Direction.Right\n            )\n            {\n                throw new IndexOutOfRangeException($\"Cannot move cell at row={row} col={col} in Direction={dir}\");\n            }\n","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/com.unity.ml-agents/Runtime/Integrations/Match3/Move.cs#L138-L174","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Clamp/validate row against board.MaxRows (or the actual board's Rows) before calling FromPositionAndDirection","Only generate moves from valid cell coordinates (iterate board.Cells or use board validity checks)","Use BoardSize values consistent with the actual board dimensions"],"exampleFix":"// before\nvar move = Move.FromPositionAndDirection(actionRow, actionCol, dir, board.MaxBoardSize);\n// after\nactionRow = Mathf.Clamp(actionRow, 0, board.Rows - 1);\nvar move = board.CheckMove(actionRow, actionCol, dir); // returns null if invalid","handlingStrategy":"validation","validationCode":"bool CanPlace(int row, int col, BoardSize size) =>\n    row >= 0 && row < size.Rows && col >= 0 && col < size.Columns;\n// before calling: if (!CanPlace(row, col, board.MaxBoardSize)) skip/retry;","typeGuard":"bool IsValidRow(int row, BoardSize size) => row >= 0 && row < size.Rows;","tryCatchPattern":"try { var move = Move.FromPositionAndDirection(row, col, dir, board.MaxBoardSize); }\ncatch (IndexOutOfRangeException e) when (e.Message.StartsWith(\"row was\"))\n{ row = Mathf.Clamp(row, 0, board.MaxBoardSize.Rows - 1); }","preventionTips":["Clamp agent-emitted action values to valid row/column ranges before constructing moves","Prefer board.CheckMove / valid-move enumeration over raw coordinate construction","Keep maxBoardSize in sync with the actual board dimensions","Watch for row/col argument-order mistakes"],"tags":["unity","ml-agents","match3","index-out-of-range","bounds"],"backgroundTag":"grid-coordinate-out-of-bounds","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}