invoke-ai/InvokeAI · error · ValueError
Invalid cfg_scale_end_step. Out of range: {cfg_scale_end_ste
Error message
Invalid cfg_scale_end_step. Out of range: {cfg_scale_end_step}. What it means
Analogous to the start-step check: after resolving negative indices, cfg_scale_end_step must satisfy 0 <= end < num_steps. Otherwise it would fall outside the per-step cfg list and the invocation raises with the invalid value.
Source
Thrown at invokeai/app/invocations/flux_denoise.py:655
elif isinstance(cfg_scale, list):
cfg_scale_list = cfg_scale
else:
raise ValueError(f"Unsupported cfg_scale type: {type(cfg_scale)}")
assert len(cfg_scale_list) == num_steps
# Handle negative indices for cfg_scale_start_step and cfg_scale_end_step.
start_step_index = cfg_scale_start_step
if start_step_index < 0:
start_step_index = num_steps + start_step_index
end_step_index = cfg_scale_end_step
if end_step_index < 0:
end_step_index = num_steps + end_step_index
# Validate the start and end step indices.
if not (0 <= start_step_index < num_steps):
raise ValueError(f"Invalid cfg_scale_start_step. Out of range: {cfg_scale_start_step}.")
if not (0 <= end_step_index < num_steps):
raise ValueError(f"Invalid cfg_scale_end_step. Out of range: {cfg_scale_end_step}.")
if start_step_index > end_step_index:
raise ValueError(
f"cfg_scale_start_step ({cfg_scale_start_step}) must be before cfg_scale_end_step "
+ f"({cfg_scale_end_step})."
)
# Set values outside the start and end step indices to 1.0. This is equivalent to disabling cfg_scale for those
# steps.
clipped_cfg_scale = [1.0] * num_steps
clipped_cfg_scale[start_step_index : end_step_index + 1] = cfg_scale_list[start_step_index : end_step_index + 1]
return clipped_cfg_scale
def _prep_inpaint_mask(self, context: InvocationContext, latents: torch.Tensor) -> torch.Tensor | None:
"""Prepare the inpaint mask.
- Loads the mask
- Resizes if necessaryView on GitHub (pinned to 0b6a024f2f)
Solutions
- Set cfg_scale_end_step within 0 <= end < num_steps for the current run.
- Use -1 to denote the final step instead of a hard-coded index.
- Clamp: end_index = min(max(cfg_scale_end_step, -num_steps), num_steps - 1) before calling.
Example fix
// before prep_cfg_scale(num_steps=4, cfg_scale_end_step=20) // out of range // after prep_cfg_scale(num_steps=4, cfg_scale_end_step=-1) // final step
Defensive patterns
Strategy: validation
Validate before calling
if not (0 <= cfg_scale_end_step < num_steps or -num_steps <= cfg_scale_end_step < 0):
raise ValueError('cfg_scale_end_step out of range') Type guard
def is_valid_end_step(step: int, num_steps: int) -> bool:
return -num_steps <= step < num_steps Try / catch
try:
cfg_list = denoise.prep_cfg_scale(cfg_scale, num_steps, cfg_scale_start_step=s, cfg_scale_end_step=e)
except ValueError as e:
if 'Invalid cfg_scale_end_step' in str(e):
cfg_list = denoise.prep_cfg_scale(cfg_scale, num_steps, cfg_scale_start_step=s, cfg_scale_end_step=-1)
else:
raise Prevention
- Default the end step to -1 (last step) rather than an absolute index
- Sync end-step fields with the step-count slider in the UI
- Clamp indices before calling prep_cfg_scale
When it happens
Trigger: Calling prep_cfg_scale with end_step >= num_steps or < -num_steps (e.g. end_step=20 for a 4-step Schnell run); the end-step slider retaining a value from a longer run.
Common situations: Reducing step count in the UI without adjusting the end step; editing workflow JSON manually; reusing a shared CFG-schedule node across graphs with different step counts.
Related errors
- Invalid cfg_scale_start_step. Out of range: {cfg_scale_start
- cfg_scale_start_step ({cfg_scale_start_step}) must be before
- Unsupported cfg_scale type: {type(cfg_scale)}
- cfg_scale values must be finite.
- cfg_scale must be greater than 1
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/a2b29df075e7deea.
Report an issue: GitHub.