Comfy-Org/ComfyUI · error · RuntimeError

TripoSplat gaussian decoder: use the 'TripoSplat Decode' (VA

Error message

TripoSplat gaussian decoder: use the 'TripoSplat Decode' (VAEDecodeTripoSplat)

What it means

The TripoSplat octree Gaussian decoder ('gs.base_offset_scale' + 'octree.out_proj.weight' checkpoints) does not return tensors from encode/decode: it produces structured GaussianSplat objects and manages its own VRAM. The generic VAE.encode/decode entry points are therefore replaced with a stub raising this RuntimeError, pointing users to the dedicated VAEDecodeTripoSplat node.

Source

Thrown at comfy/sd.py:1041

                self.working_dtypes = [torch.float32]
                # encode gets the waveform shape [B, 2, samples], decode the latent shape [B, 32, 2, T]
                def estimate_encode_memory(samples, dtype):
                    return (900 * samples + 105_000_000) * model_management.dtype_size(dtype) * 1.03

                def estimate_decode_memory(samples, dtype):
                    return max(42_000_000, 220 * samples + 20_000_000) * model_management.dtype_size(dtype) * 1.03

                self.memory_used_encode = lambda shape, dtype: estimate_encode_memory(shape[2], dtype)
                self.memory_used_decode = lambda shape, dtype: estimate_decode_memory(shape[-1] * self.upscale_ratio, dtype)
            elif "gs.base_offset_scale" in sd and "octree.out_proj.weight" in sd:  # TripoSplat octree gaussian decoder
                self.first_stage_model = comfy.ldm.triposplat.vae.OctreeGaussianDecoder()
                self.latent_channels = 16
                self.latent_dim = 1
                self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
                # The generic VAE.encode/decode path isn't used: VAEDecodeTripoSplat calls the gaussian
                # decoder directly (structured GaussianSplat objects, not a tensor and reserves VRAM itself from num_gaussians.
                def _no_generic_io(*args, **kwargs):
                    raise RuntimeError("TripoSplat gaussian decoder: use the 'TripoSplat Decode' (VAEDecodeTripoSplat)")
                self.memory_used_encode = self.memory_used_decode = _no_generic_io
            else:
                logging.warning("WARNING: No VAE weights detected, VAE not initalized.")
                self.first_stage_model = None
                return
        else:
            self.first_stage_model = AutoencoderKL(**(config['params']))
        self.first_stage_model = self.first_stage_model.eval()

        if device is None:
            device = model_management.vae_device()
        self.device = device
        offload_device = model_management.vae_offload_device()
        if dtype is None:
            dtype = model_management.vae_dtype(self.device, self.working_dtypes)
        self.vae_dtype = dtype
        self.first_stage_model.to(self.vae_dtype)
        model_management.archive_model_dtypes(self.first_stage_model)

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Use the 'TripoSplat Decode' (VAEDecodeTripoSplat) node to decode TripoSplat latents into Gaussian splats.
  2. Branch on the VAE checkpoint keys (presence of 'gs.base_offset_scale' and 'octree.out_proj.weight') or the decoder class before choosing the decode path.
  3. Do not connect this VAE to encode nodes; TripoSplat generation starts from model latents.

Example fix

# before
images = vae.decode(latent)  # RuntimeError for TripoSplat octree VAE

# after
# in the workflow use node: VAEDecodeTripoSplat(vae, samples) -> GAUSSIAN_SPLATS
splats = nodes.VAEDecodeTripoSplat().decode(vae, latent)[0]
Defensive patterns

Strategy: validation

Validate before calling

sd_keys = vae_sd.keys()
is_tripo_splat = 'gs.base_offset_scale' in sd_keys and 'octree.out_proj.weight' in sd_keys
assert not is_tripo_splat or use_tripo_node, 'Use VAEDecodeTripoSplat for the TripoSplat octree VAE'

Type guard

def is_tripo_splat_vae(vae) -> bool:
    return isinstance(getattr(vae, 'first_stage_model', None),
                      comfy.ldm.triposplat.vae.OctreeGaussianDecoder)

Try / catch

try:
    out = vae.decode(latent)
except RuntimeError as e:
    if 'TripoSplat' in str(e):
        raise SystemExit('Decode TripoSplat latents with the VAEDecodeTripoSplat node.')
    raise

Prevention

When it happens

Trigger: Loading a TripoSplat VAE and connecting it to VAEDecode, VAEEncode, VAEDecodeTiled, or any custom node that calls vae.decode(latents) expecting an image tensor; generic workflow templates applied to a TripoSplat model.

Common situations: Reusing image-VAE workflows for the TripoSplat 3D model; custom nodes that call first_stage_model decode generically; API consumers assuming every VAE yields tensors.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/f8b3fecfd8e76d12. Report an issue: GitHub.