3b1b/manim · error · Exception

Functions passed to ApplyFunction must return object of type

Error message

Functions passed to ApplyFunction must return object of type Mobject

What it means

ApplyFunction creates its target by running the user-supplied function on a copy of the mobject; create_target verifies the return value is a Mobject. Functions that return None (mutating in place without returning) or any non-Mobject trigger the Exception.

Source

Thrown at manimlib/animation/transform.py:263

        if not hasattr(mobject, "saved_state") or mobject.saved_state is None:
            raise Exception("Trying to restore without having saved")
        super().__init__(mobject, mobject.saved_state, **kwargs)


class ApplyFunction(Transform):
    def __init__(
        self,
        function: Callable[[Mobject], Mobject],
        mobject: Mobject,
        **kwargs
    ):
        self.function = function
        super().__init__(mobject, **kwargs)

    def create_target(self) -> Mobject:
        target = self.function(self.mobject.copy())
        if not isinstance(target, Mobject):
            raise Exception("Functions passed to ApplyFunction must return object of type Mobject")
        return target


class ApplyMatrix(ApplyPointwiseFunction):
    def __init__(
        self,
        matrix: npt.ArrayLike,
        mobject: Mobject,
        **kwargs
    ):
        matrix = self.initialize_matrix(matrix)

        def func(p):
            return np.dot(p, matrix.T)

        super().__init__(func, mobject, **kwargs)

    def initialize_matrix(self, matrix: npt.ArrayLike) -> np.ndarray:

View on GitHub (pinned to dee01804d4)

Solutions

  1. Make the function return the mobject: def f(m): m.scale(2); m.set_color(RED); return m
  2. For lambdas, chain method calls since each returns the mobject: lambda m: m.scale(2).set_color(RED)
  3. If you only need pointwise mapping, use ApplyPointwiseFunction instead

Example fix

# before
self.play(ApplyFunction(lambda m: m.scale(2).set_color(RED), mob))  # if a branch returns None
# after
def grow(m):
    m.scale(2).set_color(RED)
    return m
self.play(ApplyFunction(grow, mob))
Defensive patterns

Strategy: validation

Validate before calling

def apply_and_return(m):
    result = my_func(m)
    assert isinstance(result, Mobject), "function must return a Mobject"
    return result
self.play(ApplyFunction(apply_and_return, mob))

Type guard

def returns_mobject(fn, sample: Mobject) -> bool:
    return isinstance(fn(sample.copy()), Mobject)

Prevention

When it happens

Trigger: ApplyFunction(lambda m: m.scale(2), mob) works only because mobject methods return self; a lambda like lambda m: m.scale(2) and None or a function whose last statement is a non-returning call fails; returning a tuple (mobject, value) also fails.

Common situations: Writing a function that mutates the mobject but forgets to return it — very easy with lambdas whose body is a statement-like call; functions adapted from scene code that never needed a return value.

Related errors


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