{"record":{"id":"75ebee3c801fb272","repo":"invoke-ai/InvokeAI","slug":"negative-text-conditioning-is-required-when-cfg-sc-75ebee","errorCode":null,"errorMessage":"Negative text conditioning is required when cfg_scale is not 1.0.","messagePattern":"Negative text conditioning is required when cfg_scale is not 1\\.0\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/flux2/denoise.py","lineNumber":171,"sourceCode":"                txt_ids=txt_ids,\n                guidance=guidance_vec,\n                joint_attention_kwargs=pos_joint_attention_kwargs,\n                return_dict=False,\n            )\n\n            # Extract the sample from the output (return_dict=False returns tuple)\n            pred = output[0] if isinstance(output, tuple) else output\n\n            # Drop the prediction for the reference tokens - they are context, not sampled state.\n            if img_cond_seq is not None:\n                pred = pred[:, :original_seq_len]\n\n            step_cfg_scale = cfg_scale[min(user_step, len(cfg_scale) - 1)]\n\n            # Apply CFG if scale is not 1.0\n            if not math.isclose(step_cfg_scale, 1.0):\n                if neg_txt is None:\n                    raise ValueError(\"Negative text conditioning is required when cfg_scale is not 1.0.\")\n\n                neg_output = model(\n                    hidden_states=img_input,\n                    encoder_hidden_states=neg_txt,\n                    timestep=t_vec,\n                    img_ids=model_img_ids,\n                    txt_ids=neg_txt_ids if neg_txt_ids is not None else txt_ids,\n                    guidance=guidance_vec,\n                    return_dict=False,\n                )\n\n                neg_pred = neg_output[0] if isinstance(neg_output, tuple) else neg_output\n                if img_cond_seq is not None:\n                    neg_pred = neg_pred[:, :original_seq_len]\n                pred = neg_pred + step_cfg_scale * (pred - neg_pred)\n\n            # Use scheduler.step() for the update\n            step_output = scheduler.step(model_output=pred, timestep=timestep, sample=img)","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/flux2/denoise.py#L153-L189","documentation":"In flux2 denoise, when a per-step classifier-free-guidance scale deviates from 1.0, the loop must run the model a second time on negative text conditioning (neg_txt). If cfg_scale != 1.0 but neg_txt is None, CFG cannot be computed, so denoise raises ValueError early instead of producing incorrect output.","triggerScenarios":"Calling denoise with cfg_scale (scalar or per-step list) != 1.0 while neg_txt is None — e.g. building text embeddings only for the positive prompt, or omitting negative prompt processing in a custom pipeline around Flux2.","commonSituations":"Custom Flux2 sampling loops that skip encoding the negative prompt; pipelines migrated from CFG-free Flux.1 where negative conditioning was unused; per-step cfg_scale lists where any step differs from 1.0.","solutions":["Encode the negative prompt and pass its embeddings as neg_txt to denoise","Set cfg_scale to 1.0 (or a list of all 1.0s) if you don't want CFG and have no negative prompt","Ensure the per-step cfg_scale slice actually equals 1.0 for steps where neg_txt is absent"],"exampleFix":"// before\noutput = denoise(model=..., img=..., cfg_scale=3.5, neg_txt=None, ...)\n// after\nneg_txt = encode_prompt(negative_prompt)  # encode negative prompt\noutput = denoise(model=..., img=..., cfg_scale=3.5, neg_txt=neg_txt, ...)","handlingStrategy":"validation","validationCode":"if any(not math.isclose(s, 1.0) for s in (cfg_scale if isinstance(cfg_scale, list) else [cfg_scale])):\n    assert neg_txt is not None, \"cfg_scale != 1.0 requires neg_txt\"","typeGuard":null,"tryCatchPattern":"try:\n    latents = denoise(..., cfg_scale=cfg_scale, neg_txt=neg_txt)\nexcept ValueError as e:\n    if \"Negative text conditioning\" in str(e):\n        neg_txt = encode_prompt(\"\")\n        latents = denoise(..., cfg_scale=cfg_scale, neg_txt=neg_txt)\n    else:\n        raise","preventionTips":["Always encode the negative prompt when CFG is enabled","Treat cfg_scale>1.0 and neg_txt as a coupled pair in pipeline code","Encode an empty-string negative prompt as a safe default"],"tags":["flux2","cfg","missing-argument","denoising"],"backgroundTag":"missing-required-argument","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}