{"record":{"id":"36295b1e699bf566","repo":"sgl-project/sglang","slug":"sana-forward-pass-requires-encoder-hidden-states","errorCode":null,"errorMessage":"SANA forward pass requires encoder_hidden_states","messagePattern":"SANA forward pass requires encoder_hidden_states","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/sana.py","lineNumber":580,"sourceCode":"            arch.patch_size * arch.patch_size * self.out_channels,\n            bias=True,\n        )\n\n        self.layer_names = [\"transformer_blocks\"]\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        encoder_hidden_states: torch.Tensor = None,\n        timestep: torch.LongTensor = None,\n        guidance: torch.Tensor = None,\n        encoder_attention_mask: torch.Tensor = None,\n        **kwargs,\n    ) -> torch.Tensor:\n\n        # Input validation - fail fast\n        if encoder_hidden_states is None:\n            raise ValueError(\"SANA forward pass requires encoder_hidden_states\")\n\n        batch_size, channels, height, width = hidden_states.shape\n        p = self.patch_size\n        post_patch_height = height // p\n        post_patch_width = width // p\n\n        hidden_states = _mps_safe_conv2d(self.patch_embed[\"proj\"], hidden_states)\n        # One layout conversion here prevents every downstream LayerNorm from\n        # copying the transposed patch view independently.\n        hidden_states = hidden_states.flatten(2).transpose(1, 2).contiguous()\n\n        timestep_emb, embedded_timestep = self.time_embed(\n            timestep, hidden_dtype=hidden_states.dtype\n        )\n\n        if isinstance(encoder_attention_mask, (list, tuple)):\n            encoder_attention_mask = encoder_attention_mask[0]\n","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/sana.py#L562-L598","documentation":"SANA's forward performs fail-fast validation: encoder_hidden_states (text captions embeddings) is mandatory; None raises immediately since the cross-attention has nothing to condition on.","triggerScenarios":"Calling the DiT forward with encoder_hidden_states=None (e.g. unconditional generation path or an empty-prompt path that skipped the text encoder).","commonSituations":"Implementing classifier-free guidance where one batch leg forgets to run the text encoder (even null prompts need embeddings); pipeline refactor dropping the caption tensor.","solutions":["Always run the text encoder (even for null/negative prompts) and pass its embeddings","For CFG, pass both cond and uncond embeddings (often stacked) rather than None","Check pipeline code paths where captions may be empty"],"exampleFix":"# before\nout = dit(hidden_states=latents, timestep=t, encoder_hidden_states=None)\n# after\nnull_emb = text_encoder(tokenize(\"\"), **encoder_kwargs)\nout = dit(hidden_states=latents, timestep=t, encoder_hidden_states=null_emb)","handlingStrategy":"validation","validationCode":"assert encoder_hidden_states is not None, \"SANA requires caption embeddings (encode null prompts for uncond)\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always run the text encoder, even for empty/negative prompts","Stack cond/uncond embeddings for CFG instead of passing None"],"tags":["sana","encoder-hidden-states","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}