invoke-ai/InvokeAI · error · ValueError
{type(scheduler).__name__} does not accept an explicit sigma
Error message
{type(scheduler).__name__} does not accept an explicit sigma schedule, so it cannot honor denoising_start/denoising_end. Use the euler or lcm scheduler for partial denoising. What it means
In ernie_image denoise, partial denoising (denoising_start/denoising_end) requires installing an explicit sigma schedule on the scheduler. FlowMatchHeunDiscreteScheduler.set_timesteps only accepts a step count and derives its own sigmas, so when the requested window doesn't span the full 1.0->0.0 range, the library raises ValueError instead of silently running a full denoise with the wrong schedule.
Source
Thrown at invokeai/backend/ernie_image/denoise.py:93
if use_scheduler:
set_timesteps_sig = inspect.signature(scheduler.set_timesteps)
if "sigmas" in set_timesteps_sig.parameters:
# Hand the scheduler the *whole* window -- terminal sigma included -- and then drop the
# extra zero it unconditionally appends. Passing `timesteps[:-1]` instead would let that
# appended zero stand in for the requested end sigma, so `denoising_end < 1.0` would
# silently run a full denoise in fewer, coarser steps rather than stopping early.
# Truncating (instead of patching the last sigma by hand) keeps the scheduler's own
# `shift` applied to the terminal sigma, which manual math here would get wrong.
scheduler.set_timesteps(sigmas=list(timesteps), device=img.device)
scheduler.sigmas = scheduler.sigmas[:-1]
scheduler.timesteps = scheduler.timesteps[:-1]
else:
# FlowMatchHeunDiscreteScheduler.set_timesteps only takes a step count and derives its
# own sigmas, so a partial-denoise range cannot be honored. Refuse instead of silently
# running a full denoise with the wrong schedule.
if not (math.isclose(timesteps[0], 1.0) and math.isclose(timesteps[-1], 0.0, abs_tol=1e-6)):
raise ValueError(
f"{type(scheduler).__name__} does not accept an explicit sigma schedule, so it cannot honor "
"denoising_start/denoising_end. Use the euler or lcm scheduler for partial denoising."
)
scheduler.set_timesteps(num_inference_steps=len(timesteps) - 1, device=img.device)
if init_latents is not None:
# `scheduler.sigmas[0]` is the *shifted* first sigma; `timesteps[0]` is the raw one.
# Blending at the raw value would build a sample at one sigma and then tell the first
# model call it is at another. Equivalent to `scheduler.scale_noise`, spelled out
# because it has to agree with the Euler math below.
img = _blend_init_latents(init_latents, img, float(scheduler.sigmas[0]))
# Higher-order solvers evaluate the model more than once per requested step (Heun's
# `set_timesteps(N)` yields 2N-1 timesteps), so drive progress off the actual iteration
# count rather than the requested step count.
total_steps = len(scheduler.timesteps)
pbar = tqdm(total=total_steps, desc="ERNIE-Image denoising")View on GitHub (pinned to 0b6a024f2f)
Solutions
- Switch the scheduler to euler or lcm, which accept explicit sigma schedules and honor partial denoising.
- Set denoising_start=0.0 and denoising_end=1.0 if you must keep Heun (full denoise only).
- Adjust graph/UI logic to restrict the Heun option to full denoise runs.
Example fix
// before denoise(model, scheduler=FlowMatchHeunDiscreteScheduler(...), denoising_start=0.4) // after denoise(model, scheduler=EulerDiscreteScheduler(...), denoising_start=0.4)
Defensive patterns
Strategy: fallback
Validate before calling
is_heun = isinstance(scheduler, FlowMatchHeunDiscreteScheduler)
is_partial = denoising_start > 0.0 or denoising_end < 1.0
if is_heun and is_partial:
scheduler = switch_to_euler(scheduler) Type guard
def supports_explicit_sigmas(scheduler) -> bool:
return not isinstance(scheduler, FlowMatchHeunDiscreteScheduler) Try / catch
try:
denoise(model, scheduler=scheduler, denoising_start=s, denoising_end=e)
except ValueError as e:
if "explicit sigma schedule" in str(e):
scheduler = EulerDiscreteScheduler.from_config(scheduler.config)
return denoise(model, scheduler=scheduler, denoising_start=s, denoising_end=e)
raise Prevention
- Restrict partial-denoise UI controls to euler/lcm schedulers.
- Assert scheduler capability before setting denoising_start/end.
- Default new graphs to euler when partial denoising is enabled.
When it happens
Trigger: Calling denoise() with scheduler=FlowMatchHeunDiscreteScheduler and either denoising_start > 0 or denoising_end < 1.0 (i.e. timesteps slice endpoints not ~1.0 and ~0.0 within 1e-6).
Common situations: Users selecting the Heun scheduler in the UI and then setting a denoise start/end for img2img or preview; graphs that pass partial-denoise windows with Heun after switching schedulers from euler/lcm.
Related errors
- User not found or inactive
- Missing authentication credentials
- User account is inactive or does not exist
- Authentication required
- Invalid denoising window: start={denoising_start}, end={deno
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/e9b4e528defec80d.
Report an issue: GitHub.