Comfy-Org/ComfyUI · error · ValueError
MergeSplat: no gaussians to merge
Error message
MergeSplat: no gaussians to merge
What it means
Raised by _merge_gaussians when every element of the incoming gaussian list is None (after filtering). The merge helper is expected at least one real SPLAT to determine the output batch size and SH degree; with nothing connected it has no shape information and cannot construct a result. It is the internal backstop behind the MergeSplat node's own input check.
Source
Thrown at comfy_extras/nodes_gaussian_splat.py:1182
if cls.hidden.unique_id: # show the count inline on the node
PromptServer.instance.send_progress_text(f"{count:,} splats", cls.hidden.unique_id)
return IO.NodeOutput(splat, count)
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)View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Connect at least one splat input to MergeSplat.
- Unmute/unbypass the upstream nodes feeding the merge.
- If merging conditionally in code, filter Nones first and ensure the list is non-empty before calling.
Example fix
// before merged = _merge_gaussians([None, None]) // after gs = [g for g in splats if g is not None] merged = _merge_gaussians(gs) if gs else None
Defensive patterns
Strategy: validation
Validate before calling
gs = [g for g in gaussians if g is not None]
if not gs:
raise ValueError('MergeSplat: connect at least one splat')
merged = _merge_gaussians(gs) Type guard
def has_any_splat(gaussians: list) -> bool:
return any(g is not None for g in gaussians) Try / catch
try:
merged = _merge_gaussians(gs)
except ValueError as e:
if 'no gaussians to merge' in str(e):
merged = None # or wire a default splat
else:
raise Prevention
- Filter None inputs before merging.
- Ensure at least one upstream splat node is active (not muted/bypassed).
When it happens
Trigger: MergeSplat with all Autogrow inputs unconnected (caught one level up at line 1237), or a caller invoking _merge_gaussians directly with a list of Nones — e.g., optional upstream nodes that returned None on their empty path.
Common situations: Workflow branches where every upstream splat node was bypassed/muted; optional inputs that all evaluated to None; programmatic misuse of the private helper.
Related errors
- MergeSplat: connect at least one splat.
- SplatToFile3D: gaussian is empty
- File3DToSplat: .ksplat has no splats
- Unsupported splat format: {format!r}
- MergeSplat: batch size mismatch ({b} vs {g.positions.shape[0
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/a1e5bc6f73d08028.
Report an issue: GitHub.