invoke-ai/InvokeAI · error · ValueError
denoising_start must be less than denoising_end.
Error message
denoising_start must be less than denoising_end.
What it means
`_validate_inputs` enforces that the denoising window is a valid interval: denoising_start must be strictly less than denoising_end. Equal or inverted values define an empty or reversed range and are rejected before scheduling.
Source
Thrown at invokeai/app/invocations/krea2_denoise.py:231
)
return self.cfg_scale
raise ValueError(f"Invalid CFG scale type: {type(self.cfg_scale)}")
@staticmethod
def _should_apply_cfg_for_step(cfg_scale: float, *, has_negative_conditioning: bool) -> bool:
return has_negative_conditioning and cfg_scale > 1.0
@staticmethod
def _validate_effective_schedule(*, start_idx: int, end_idx: int) -> None:
if end_idx <= start_idx:
raise ValueError(
"The requested denoising range does not contain any effective denoising steps at the configured "
"step count. Increase denoising_end, decrease denoising_start, or increase steps."
)
def _validate_inputs(self) -> None:
if self.denoising_start >= self.denoising_end:
raise ValueError("denoising_start must be less than denoising_end.")
if self.denoise_mask is not None and self.latents is None:
raise ValueError("Initial latents are required when a denoise mask is provided.")
def _is_distilled(self, context: InvocationContext) -> bool:
"""Whether the transformer is the distilled Turbo checkpoint (fixed mu) vs. Raw (dynamic mu).
Prefer the classified variant (works for diffusers, single-file and GGUF alike); fall back to
the pipeline-level ``is_distilled`` flag in model_index.json, then default to distilled.
A failed config lookup is a real error and is allowed to propagate — silently defaulting to the
Turbo shift would apply the wrong sampling schedule to a Raw model.
"""
from invokeai.backend.model_manager.taxonomy import Krea2VariantType
config = context.models.get_config(self.transformer.transformer)
variant = getattr(config, "variant", None)
if variant is not None:
return variant != Krea2VariantType.BaseView on GitHub (pinned to 0b6a024f2f)
Solutions
- Set denoising_end strictly greater than denoising_start (e.g. start=0.5, end=1.0).
- Add a caller-side clamp: if start >= end, widen end or reset to defaults (0.0 / 1.0).
- Fix swapped variables in scripts that compute the range dynamically.
Example fix
// before denoising_start=0.9; denoising_end=0.5 // after denoising_start, denoising_end = min(0.5, 0.9), max(0.5, 0.9) # 0.5, 0.9
Defensive patterns
Strategy: validation
Validate before calling
if denoising_start >= denoising_end:
raise ValueError(f"denoising_start ({denoising_start}) must be < denoising_end ({denoising_end})") Type guard
def is_valid_denoise_window(start: float, end: float) -> bool:
return 0.0 <= start < end <= 1.0 Try / catch
try:
out = invoke_krea2_denoise(denoising_start=start, denoising_end=end)
except ValueError as e:
if "must be less than denoising_end" in str(e):
start, end = sorted((start, end))
out = invoke_krea2_denoise(denoising_start=start, denoising_end=end)
else:
raise Prevention
- Normalize the window with min/max before constructing the invocation.
- Constrain UI sliders so end cannot drop to or below start.
- Assert window validity in workflow-generation code.
When it happens
Trigger: Setting denoising_start >= denoising_end on the krea2_denoise invocation, e.g. start=0.8, end=0.8, or swapped values like start=0.9, end=0.5.
Common situations: UI slider ranges that can collapse to equal values; programmatically generated graphs where start/end variables are swapped; refiner setups configured with a zero-width window.
Related errors
- The requested denoising range does not contain any effective
- denoising_start should be 0 when initial latents are not pro
- per_layer_weights must be comma-separated numbers: {e}
- per_layer_weights must have exactly {_NUM_TEXT_LAYERS} value
- per_layer_weights must contain only finite values.
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/3b0d7bac58f3ceea.
Report an issue: GitHub.