Comfy-Org/ComfyUI · error · ValueError
MergeSplat: batch size mismatch ({b} vs {g.positions.shape[0
Error message
MergeSplat: batch size mismatch ({b} vs {g.positions.shape[0]}). What it means
Raised by _merge_gaussians when the input SPLATs disagree on batch size (positions.shape[0]). Merge is defined per batch item — it concatenates each item's gaussians across inputs and pads SH to the max degree — so every input must carry the same number of items. The first input's batch size is the reference; any deviation raises with both values.
Source
Thrown at comfy_extras/nodes_gaussian_splat.py:1186
def _pad_stack(items, n):
# Stack a list of (Lᵢ, *tail) tensors into (B, n, *tail), zero-padding each row up to n.
tail = items[0].shape[1:]
out = items[0].new_zeros((len(items), n, *tail))
for i, t in enumerate(items):
out[i, :t.shape[0]] = t
return out
def _merge_gaussians(gaussians: list) -> Types.SPLAT:
# Concatenate SPLAT batches along the splat dimension (per item), padding SH to the highest degree.
gs = [g for g in gaussians if g is not None]
if not gs:
raise ValueError("MergeSplat: no gaussians to merge")
b = gs[0].positions.shape[0]
for g in gs:
if g.positions.shape[0] != b:
raise ValueError(f"MergeSplat: batch size mismatch ({b} vs {g.positions.shape[0]}).")
max_k = max(g.sh.shape[2] for g in gs)
pos_b, scl_b, rot_b, op_b, sh_b, lengths = [], [], [], [], [], []
for i in range(b):
pos_i, scl_i, rot_i, op_i, sh_i = [], [], [], [], []
for g in gs:
end = _real_len(g, i)
pos_i.append(g.positions[i, :end])
scl_i.append(g.scales[i, :end])
rot_i.append(g.rotations[i, :end])
op_i.append(g.opacities[i, :end])
sh = g.sh[i, :end] # (end, K, 3)
if sh.shape[1] < max_k: # zero-pad lower-degree SH
sh = torch.cat([sh, sh.new_zeros(sh.shape[0], max_k - sh.shape[1], sh.shape[2])], dim=1)
sh_i.append(sh)
pos_b.append(torch.cat(pos_i))
scl_b.append(torch.cat(scl_i))
rot_b.append(torch.cat(rot_i))View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Make all merged splats share a batch size: select the same batch item (slice/re-batch) before merging.
- If one input is single-item, expand or pick matching items so shapes align.
- Check each upstream node's batch dimension (positions.shape[0]) and align them.
Example fix
# before: batch sizes 1 and 4 merged = _merge_gaussians([splat_b1, splat_b4]) # after: align to the same item count merged = _merge_gaussians([splat_b1, splat_b4[0:1]])
Defensive patterns
Strategy: validation
Validate before calling
sizes = {g.positions.shape[0] for g in gs}
if len(sizes) > 1:
raise ValueError(f'MergeSplat batch mismatch: {sizes}; align batch sizes first')
merged = _merge_gaussians(gs) Type guard
def same_batch_size(gs: list) -> bool:
return len({g.positions.shape[0] for g in gs}) == 1 Try / catch
try:
merged = _merge_gaussians(gs)
except ValueError as e:
if 'batch size mismatch' in str(e):
b = gs[0].positions.shape[0]
gs = [g[:b] for g in gs] # align to first input's batch
merged = _merge_gaussians(gs)
else:
raise Prevention
- Select matching batch items before merging (File3DToSplat yields batch size 1).
- Assert equal positions.shape[0] on all merge inputs in the workflow.
When it happens
Trigger: Merging a splat with batch size 1 against one with batch size 4 (e.g., one decoded from a batched latent, another loaded from a single-item file via File3DToSplat); mixing sources with different item counts in MergeSplat.
Common situations: One input from a batched generation node and another from a single loaded file; upstream nodes that changed batch handling after a workflow edit.
Related errors
- MergeSplat: no gaussians to merge
- ASSET_NOT_FOUND
- Image-token count {image_idx.shape[0]} != ViT output count {
- attention_mask must be {expected}, got {tuple(attention_mask
- {name} inner dimension {inner_dim} is not divisible by head
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/117eed61f787158b.
Report an issue: GitHub.