{"record":{"id":"cc3af70865a17655","repo":"sgl-project/sglang","slug":"unsupported-vae-encode-output-for-sana-wm-first-fr","errorCode":null,"errorMessage":"Unsupported VAE encode output for SANA-WM first-frame conditioning: {type(encoded).__name__}","messagePattern":"Unsupported VAE encode output for SANA-WM first-frame conditioning: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/base.py","lineNumber":1149,"sourceCode":"    def _extract_vae_latents(encoded: Any) -> torch.Tensor:\n        \"\"\"Return deterministic VAE latents from common Diffusers outputs.\"\"\"\n        latent_dist = getattr(encoded, \"latent_dist\", None)\n        if latent_dist is not None:\n            if hasattr(latent_dist, \"mode\"):\n                return latent_dist.mode()\n            mean = getattr(latent_dist, \"mean\", None)\n            if isinstance(mean, torch.Tensor):\n                return mean\n            if callable(mean):\n                return mean()\n            if hasattr(latent_dist, \"sample\"):\n                return latent_dist.sample()\n\n        if isinstance(encoded, tuple) and encoded:\n            return SanaWMBeforeDenoisingStage._extract_vae_latents(encoded[0])\n        if isinstance(encoded, torch.Tensor):\n            return encoded\n        raise TypeError(\n            \"Unsupported VAE encode output for SANA-WM first-frame conditioning: \"\n            f\"{type(encoded).__name__}\"\n        )\n\n    def _prepare_noise_latents(\n        self,\n        shape: tuple,\n        dtype: torch.dtype,\n        device: torch.device,\n        generator: (\n            torch.Generator | list[torch.Generator] | tuple[torch.Generator, ...]\n        ),\n    ) -> torch.Tensor:\n        if isinstance(generator, (list, tuple)):\n            if not generator:\n                raise ValueError(\"SANA-WM generator list must not be empty.\")\n            if len(generator) == 1:\n                return randn_tensor(","sourceCodeStart":1131,"sourceCodeEnd":1167,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/base.py#L1131-L1167","documentation":"Raised by _extract_vae_latents when the VAE encode() output is neither an object with a latent_dist/sample-able attribute, a non-empty tuple, nor a torch.Tensor — i.e. the VAE returned an unexpected type.","triggerScenarios":"Swapping in a custom/different VAE whose encode returns e.g. a dict, a list, or None; VAE version mismatch changing the return type. Called via _vae_encode_image / _encode_first_frame.","commonSituations":"Upgrading diffusers and the return wrapper changed; using a custom VAE wrapper; monkeypatched VAE in tests returning a plain object.","solutions":["Make the custom VAE return a tensor or a tuple whose first element holds latents","Unwrap the latents before returning from a wrapper encode()","Pin/align the diffusers VAE API version the stage expects"],"exampleFix":"# before\ndef encode(self, z): return {'latents': lat}\n# after\ndef encode(self, z): return (lat,)  # tuple; first element extracted","handlingStrategy":"type-guard","validationCode":"out = vae.encode(x)\nassert isinstance(out, (torch.Tensor, tuple)) or hasattr(out, 'latent_dist')","typeGuard":"def vae_output_usable(encoded) -> bool:\n    return isinstance(encoded, torch.Tensor) or (isinstance(encoded, tuple) and encoded) or hasattr(encoded, 'latent_dist')","tryCatchPattern":null,"preventionTips":["Pin the diffusers version the stage was built against","Wrap custom VAEs to return tensors"],"tags":["vae","encode-output","compatibility","sana-wm"],"backgroundTag":"unsupported-return-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}