{"record":{"id":"9750c0c9183752b3","repo":"sgl-project/sglang","slug":"sana-wm-streaming-cfg-requires-negative-prompt-emb","errorCode":null,"errorMessage":"SANA-WM streaming CFG requires negative prompt embeds.","messagePattern":"SANA-WM streaming CFG requires negative prompt embeds\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/streaming.py","lineNumber":477,"sourceCode":"            dtype=target_dtype,\n        )\n        pos_mask = _to_device_dtype(\n            _first_tensor(batch.prompt_attention_mask), device=device\n        )\n        if pos_embeds is None:\n            raise ValueError(\"SANA-WM streaming requires positive prompt embeds.\")\n        neg_embeds = neg_mask = None\n        if do_cfg:\n            neg_embeds = _to_device_dtype(\n                _first_tensor(pcfg.get_neg_prompt_embeds(batch)),\n                device=device,\n                dtype=target_dtype,\n            )\n            neg_mask = _to_device_dtype(\n                _first_tensor(batch.negative_attention_mask), device=device\n            )\n            if neg_embeds is None:\n                raise ValueError(\n                    \"SANA-WM streaming CFG requires negative prompt embeds.\"\n                )\n            pos_embeds, neg_embeds, pos_mask, neg_mask = (\n                _align_sana_wm_cfg_text_conditions(\n                    pos_embeds, neg_embeds, pos_mask, neg_mask\n                )\n            )\n        embeds_in = torch.cat([neg_embeds, pos_embeds], dim=0) if do_cfg else pos_embeds\n        mask_in = _cat_optional_tensors(neg_mask, pos_mask) if do_cfg else pos_mask\n        if _SANAWM_INJECT_DIR and iload is not None and not do_cfg:\n            _cond = iload(\"cond\").to(device=device, dtype=target_dtype)\n            while _cond.dim() > embeds_in.dim():\n                _cond = _cond.squeeze(1)\n            embeds_in = _cond\n            mask_in = iload(\"cond_mask\").to(device=device)\n\n        # --- camera / plücker (FULL length; forward_long windows internally) ---\n        extra = batch.extra or {}","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/streaming.py#L459-L495","documentation":"When CFG is active in streaming (do_cfg True), negative prompt embeds (pcfg.get_neg_prompt_embeds) are mandatory. Their absence means the unconditional branch of guidance cannot be computed, so the stage raises before denoising.","triggerScenarios":"Setting streaming_cfg_scale > 1.0 with do_classifier_free_guidance but the request/pipeline never produced negative prompt embeds (no negative prompt given and no default encoded).","commonSituations":"Clients request CFG without a negative prompt; the negative-encoding stage skipped because the field was empty rather than encoding an empty-string negative; partial pipeline wiring for the CFG branch.","solutions":["Provide a negative prompt (or ensure an empty-string default is encoded) when streaming CFG is enabled","Add the negative-prompt encoding stage to the pipeline for CFG runs","Or set streaming_cfg_scale = 1.0 to disable CFG entirely"],"exampleFix":"# before\nreq.negative_prompt = None  # neg embeds never produced\n# after\nreq.negative_prompt = req.negative_prompt or \"\"\nbatch = neg_text_encode_stage.forward(batch, server_args)","handlingStrategy":"validation","validationCode":"if do_cfg:\n    assert pcfg.get_neg_prompt_embeds(batch) is not None, \"encode a negative prompt (or empty string) when streaming CFG is on\"","typeGuard":"def cfg_ready(pcfg, batch) -> bool:\n    return pcfg.get_neg_prompt_embeds(batch) is not None or not do_classifier_free_guidance(batch)","tryCatchPattern":"try:\n    resp = stage.forward(batch, server_args)\nexcept ValueError as e:\n    if \"negative prompt embeds\" in str(e):\n        sampler.streaming_cfg_scale = 1.0  # degrade to no-CFG\n        resp = stage.forward(batch, server_args)\n    else:\n        raise","preventionTips":["Encode an empty-string negative prompt by default when CFG is enabled","Wire the negative-encoding stage whenever streaming_cfg_scale > 1","Validate CFG inputs at request admission"],"tags":["sana-wm","streaming","cfg","negative-prompt","valueerror"],"backgroundTag":"missing-cfg-input","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}