3b1b/manim · error · IndexError

Index {index} out of bound for matrix with {len(self.rows)}

Error message

Index {index} out of bound for matrix with {len(self.rows)} rows

What it means

IndexError from Matrix.get_row (manimlib/mobject/matrix.py:142) with message 'Index {index} out of bound for matrix with {n} rows'. self.rows holds the row VGroups from construction; get_row enforces 0 <= index < len(self.rows), rejecting both too-large and negative indices before indexing.

Source

Thrown at manimlib/mobject/matrix.py:142

            R"\left[\begin{array}{c}",
            *len(rows) * [R"\quad \\"],
            R"\end{array}\right]",
        )))
        brackets.set_height(rows.get_height() + v_buff)
        l_bracket = brackets[:len(brackets) // 2]
        r_bracket = brackets[len(brackets) // 2:]
        l_bracket.next_to(rows, LEFT, h_buff)
        r_bracket.next_to(rows, RIGHT, h_buff)
        return VGroup(l_bracket, r_bracket)

    def get_column(self, index: int):
        if not 0 <= index < len(self.columns):
            raise IndexError(f"Index {index} out of bound for matrix with {len(self.columns)} columns")
        return self.columns[index]

    def get_row(self, index: int):
        if not 0 <= index < len(self.rows):
            raise IndexError(f"Index {index} out of bound for matrix with {len(self.rows)} rows")
        return self.rows[index]

    def get_columns(self) -> VGroup:
        return self.columns

    def get_rows(self) -> VGroup:
        return self.rows

    def set_column_colors(self, *colors: ManimColor) -> Self:
        columns = self.get_columns()
        for color, column in zip(colors, columns):
            column.set_color(color)
        return self

    def add_background_to_entries(self) -> Self:
        for mob in self.get_entries():
            mob.add_background_rectangle()
        return self

View on GitHub (pinned to dee01804d4)

Solutions

  1. Use 0-based row indices strictly less than len(matrix.get_rows())
  2. Compute bounds from the object: n_rows = len(m.get_rows()); highlight = m.get_row(n_rows - 1)
  3. Double-check whether you want get_row or get_column when data shape changed

Example fix

# before
m = Matrix([[1, 2], [3, 4]])
m.get_row(5).set_color(RED)  # raises

# after
m = Matrix([[1, 2], [3, 4]])
if 0 <= 5 < len(m.get_rows()):
    m.get_row(5).set_color(RED)
else:
    m.get_row(-0 + len(m.get_rows()) - 1).set_color(RED)
Defensive patterns

Strategy: validation

Validate before calling

n_rows = len(matrix.get_rows())
assert 0 <= row_index < n_rows, f"row_index must be in [0, {n_rows})"
row = matrix.get_row(row_index)

Type guard

def is_valid_row_index(matrix, i: int) -> bool:
    return 0 <= i < len(matrix.get_rows())

Prevention

When it happens

Trigger: Matrix([[1,2],[3,4]]).get_row(2); get_row(-1); row indices derived from matrix height that were computed for a different dataset; iterating rows of a transposed expectation (columns count vs rows count mix-up).

Common situations: Labeling/highlighting a specific row in teaching animations with a hardcoded index after shrinking the data; loops with range(len(matrix)) where matrix length equals rows but rows vs columns got swapped; 1-based indexing assumptions.

Related errors


AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14). Data as JSON: /api/errors/455ca6bd0e949c76. Report an issue: GitHub.