3b1b/manim · error · TypeError
Invalid selector: '{sel}'
Error message
Invalid selector: '{sel}' What it means
Raised by StringMobject.get_span_indication_parts path (string_mobject.py:204) when a selector in a selector list is of a type the single-selector resolver does not recognize. find_spans_by_single_selector returns None for unsupported types; inside a composite selector list that None triggers this TypeError. Valid single selectors are strings (matched against the string) and (start, end) Span tuples of ints/strings.
Source
Thrown at manimlib/mobject/svg/string_mobject.py:204
isinstance(index, int) or index is None
for index in sel
):
l = len(self.string)
span = tuple(
default_index if index is None else
min(index, l) if index >= 0 else max(index + l, 0)
for index, default_index in zip(sel, (0, l))
)
return [span]
return None
result = find_spans_by_single_selector(selector)
if result is None:
result = []
for sel in selector:
spans = find_spans_by_single_selector(sel)
if spans is None:
raise TypeError(f"Invalid selector: '{sel}'")
result.extend(spans)
return list(filter(lambda span: span[0] <= span[1], result))
@staticmethod
def span_contains(span_0: Span, span_1: Span) -> bool:
return span_0[0] <= span_1[0] and span_0[1] >= span_1[1]
# Parsing
def parse(self) -> None:
def get_substr(span: Span) -> str:
return self.string[slice(*span)]
configured_items = self.get_configured_items()
isolated_spans = self.find_spans_by_selector(self.isolate)
protected_spans = self.find_spans_by_selector(self.protect)
command_matches = self.get_command_matches(self.string)
View on GitHub (pinned to dee01804d4)
Solutions
- Use only str selectors or (start, end) tuples of int/string endpoints in selector lists
- Convert numeric indices with int() before packing them into a span tuple
- Validate each selector: isinstance(sel, str) or (isinstance(sel, tuple) and len(sel) == 2 and all(isinstance(i, (int, str)) for i in sel))
Example fix
# before mob.get_submobject_from_selector(["abc", (0.5, 1)]) # float span -> raises # after mob.get_submobject_from_selector(["abc", (0, 1)])
Defensive patterns
Strategy: type-guard
Validate before calling
def valid_selector(sel) -> bool:
if isinstance(sel, str):
return True
return (isinstance(sel, tuple) and len(sel) == 2
and all(isinstance(i, (int, str)) for i in sel))
selectors = [s for s in selectors if valid_selector(s)] Type guard
def is_valid_selector(sel) -> bool:
if isinstance(sel, str):
return True
return (isinstance(sel, tuple) and len(sel) == 2
and all(isinstance(i, (int, str)) for i in sel)) Prevention
- Use only strings or (start, end) int/string tuples as selectors
- Cast float indices with int() before building spans
- Validate selector lists in helper functions that assemble them dynamically
When it happens
Trigger: Calling mob.get_submobject_from_selector or passing sub_str_to_isolate/substrings_to_isolate with a non-str/non-tuple entry, e.g. ['abc', 3] or [(0.5, 1)] (floats, not ints) inside a composite selector list. A plain string alone does not raise (it may match nothing); the mixed list with an invalid element does.
Common situations: Programmatically building selector lists where one element is a number, a regex object, or a span with float indices; assuming regex or index floats are supported like in other APIs.
Related errors
- LaTeX compilation failed
- Unsupported: {path_verb}
- At least 2 mobjects needed for Union.
- At least 2 mobjects needed for Intersection.
- At least 2 mobjects needed for Exclusion.
AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14).
Data as JSON: /api/errors/e413c2b42e938540.
Report an issue: GitHub.