{"record":{"id":"d45204cb561cd832","repo":"invoke-ai/InvokeAI","slug":"invalid-denoising-window-start-denoising-start","errorCode":null,"errorMessage":"Invalid denoising window: start={denoising_start}, end={denoising_end}","messagePattern":"Invalid denoising window: start=(.+?), end=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/ernie_image/sampling_utils.py","lineNumber":65,"sourceCode":"            torch.zeros((0, 0, text_in_dim), device=device, dtype=dtype),\n            torch.zeros((0,), device=device, dtype=torch.long),\n        )\n\n    normalized = [\n        th.squeeze(1).to(device).to(dtype) if th.dim() == 3 else th.to(device).to(dtype) for th in text_hiddens\n    ]\n    lens = torch.tensor([t.shape[0] for t in normalized], device=device, dtype=torch.long)\n    t_max = int(lens.max().item())\n    text_bth = torch.zeros((len(normalized), t_max, text_in_dim), device=device, dtype=dtype)\n    for i, t in enumerate(normalized):\n        text_bth[i, : t.shape[0], :] = t\n    return text_bth, lens\n\n\ndef get_schedule(num_steps: int, denoising_start: float = 0.0, denoising_end: float = 1.0) -> torch.Tensor:\n    \"\"\"Linear sigma schedule from 1.0 -> 0.0, same convention as the upstream pipeline.\"\"\"\n    if not 0.0 <= denoising_start < denoising_end <= 1.0:\n        raise ValueError(f\"Invalid denoising window: start={denoising_start}, end={denoising_end}\")\n    sigmas = torch.linspace(1.0, 0.0, num_steps + 1)\n    start = int(num_steps * denoising_start)\n    end = int(num_steps * denoising_end)\n    # Slice to [start, end] inclusive of both ends so the caller can use adjacent pairs.\n    window = sigmas[start : end + 1]\n    if window.numel() < 2:\n        # A window that rounds down to a single sigma yields zero adjacent pairs, i.e. zero steps.\n        # The denoise loop would then return its input untouched and the graph would decode raw\n        # noise with no error, so refuse instead.\n        raise ValueError(\n            f\"The denoising window [{denoising_start}, {denoising_end}] rounds to zero steps at \"\n            f\"steps={num_steps}. Increase steps or widen the window.\"\n        )\n    return window\n\n\ndef vae_normalize(latents: torch.Tensor, bn: torch.nn.Module, eps: float = 1e-5) -> torch.Tensor:\n    \"\"\"Apply the VAE's BatchNorm statistics to map encoder output -> transformer input.","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/ernie_image/sampling_utils.py#L47-L83","documentation":"get_schedule builds a linear sigma schedule (1.0 -> 0.0) sliced to the [denoising_start, denoising_end) window. The window must satisfy 0 <= start < end <= 1; any other combination is ambiguous or empty and raises ValueError.","triggerScenarios":"Calling get_schedule with denoising_start >= denoising_end, a negative start, an end > 1.0, or start == end (e.g. get_schedule(20, 0.7, 0.7) or get_schedule(20, 0.5, 0.3)).","commonSituations":"UI/slider bugs passing unsorted values; graph nodes wired denoising_end into denoising_start; float inputs from percentage fields entered as 0-100 instead of 0-1.","solutions":["Ensure denoising_start < denoising_end and both are within [0, 1] before calling.","If a caller passes percentages, divide by 100 first (0-100 -> 0.0-1.0).","Swap/normalize the two values (start = min, end = max) at the graph boundary."],"exampleFix":"// before\nget_schedule(20, denoising_start=0.8, denoising_end=0.5)\n// after\nget_schedule(20, denoising_start=0.5, denoising_end=0.8)","handlingStrategy":"validation","validationCode":"assert 0.0 <= denoising_start < denoising_end <= 1.0, f\"bad window: {denoising_start}, {denoising_end}\"","typeGuard":"def is_valid_denoise_window(start: float, end: float) -> bool:\n    return 0.0 <= start < end <= 1.0","tryCatchPattern":"try:\n    sigmas = get_schedule(steps, denoising_start=s, denoising_end=e)\nexcept ValueError as e:\n    if \"Invalid denoising window\" in str(e):\n        s, e = min(s, e), max(s, e)\n        sigmas = get_schedule(steps, denoising_start=s, denoising_end=e)\n    else:\n        raise","preventionTips":["Clamp sliders so start can never exceed end in the UI.","Normalize 0-100 percentage inputs to 0-1 floats.","Validate window bounds at the graph node boundary."],"tags":["diffusion","validation","scheduler"],"backgroundTag":"invalid-parameter-range","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}