3b1b/manim · error · ValueError
No room in a block for {name}, of {size} floats
Error message
No room in a block for {name}, of {size} floats What it means
While building a uniform block's numpy dtype, each member's float size must be one of the supported GLSL/WGSL types in BLOCK_MEMBER_TYPES (uniform_block.py:31: 1='f32', 2='vec2f', 3='vec3f', 4='vec4f', 16='mat4x4f'). A member whose size isn't in that set — e.g. 5, 8, or 12 floats — has no representable block type and raises ValueError immediately.
Source
Thrown at manimlib/renderer/uniform_block.py:67
held to be compared against and sent.
"""
names: list[str] = []
formats: list[Any] = []
def add(name: str, shape: tuple[int, ...]) -> None:
names.append(name)
formats.append(np.float32 if shape == (1,) else (np.float32, shape))
size_so_far = 0
for name, size, *rest in members:
count = rest[0] if rest else 1
if count > 1 and size != ARRAY_ELEMENT_SIZE:
raise ValueError(
f"An array in a block holds {ARRAY_ELEMENT_SIZE} floats to an element, so "
f"{name} cannot hold {count} of {size}"
)
if size not in BLOCK_MEMBER_TYPES:
raise ValueError(f"No room in a block for {name}, of {size} floats")
skipped = -size_so_far % (size if size <= 2 else 4)
if skipped:
add(f"_pad{len(names)}", (skipped,))
add(name, (size,) if count == 1 else (count, size))
size_so_far += skipped + count * size
if -size_so_far % 4:
add(f"_pad{len(names)}", (-size_so_far % 4,))
# Left to pack the fields itself, numpy places them back to back, which is where the
# padding above has been chosen to put them
return np.dtype({"names": names, "formats": formats})
def uniform_block_code(dtype: np.dtype) -> str:
"""
A dtype written as the members of a shader struct, which is where a shader gets them,
leaving nothing for the two sides to disagree about. WGSL lays a struct out as std140 does
for everything declared here, so the padding uniform_block_dtype inserted is left out and
the compiler arrives at the same offsets.View on GitHub (pinned to dee01804d4)
Solutions
- Split oversized members into vec3/vec4-sized members: ('a', 3), ('b', 4) instead of ('ab', 7)
- Use size 16 for a 4x4 matrix member
- Use size 1/2/3/4/16 only — these map to f32, vec2f, vec3f, vec4f, mat4x4f
Example fix
# before
members=[('model_data', 7)]
# after
members=[('model_pos', 3), ('model_flag', 4)] Defensive patterns
Strategy: validation
Validate before calling
BLOCK_MEMBER_TYPES = {1, 2, 3, 4, 16}
for name, size, *rest in members:
assert size in BLOCK_MEMBER_TYPES, f"{name}: size {size} has no block type (use 1/2/3/4/16 floats)" Type guard
def valid_member_size(size: int) -> bool:
return size in {1, 2, 3, 4, 16} Prevention
- Think in GLSL types when writing member lists: float/vec2/vec3/vec4/mat4 only
- Split aggregates larger than 4 floats into several members; the packer inserts alignment padding for you
When it happens
Trigger: Declaring a uniform block member like ('transform', 9) or ('weights', 5) — sizes with no scalar/vector/matrix counterpart; passing sizes like 12 instead of splitting into three vec4s or using 16 for a mat4.
Common situations: Custom shaders with hand-rolled member lists; packing several logical values into one member and miscounting floats; assuming arbitrary-size arrays are allowed (they are not — arrays must be size 4, see error 52).
Related errors
- An array in a block holds {ARRAY_ELEMENT_SIZE} floats to an
- The stroke shader no longer declares {declaration!r}, so a f
AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14).
Data as JSON: /api/errors/8663074d489e6584.
Report an issue: GitHub.