Comfy-Org/ComfyUI · error · ValueError

solver_type must be 'heun' or 'midpoint'

Error message

solver_type must be 'heun' or 'midpoint'

What it means

Raised by sample_dpmpp_2m_sde when solver_type is neither 'heun' nor 'midpoint'. DPM++ 2M SDE implements exactly two second-order multistep SDE variants; the check is an exact string membership test against {'heun','midpoint'} before the Brownian tree noise sampler is constructed.

Source

Thrown at comfy/k_diffusion/sampling.py:828

        if old_denoised is None or sigmas[i + 1] == 0:
            x = (sigma_fn(t_next) / sigma_fn(t)) * x - (-h).expm1() * denoised
        else:
            h_last = t - t_fn(sigmas[i - 1])
            r = h_last / h
            denoised_d = (1 + 1 / (2 * r)) * denoised - (1 / (2 * r)) * old_denoised
            x = (sigma_fn(t_next) / sigma_fn(t)) * x - (-h).expm1() * denoised_d
        old_denoised = denoised
    return x


@torch.no_grad()
def sample_dpmpp_2m_sde(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None, solver_type='midpoint'):
    """DPM-Solver++(2M) SDE."""
    if len(sigmas) <= 1:
        return x

    if solver_type not in {'heun', 'midpoint'}:
        raise ValueError('solver_type must be \'heun\' or \'midpoint\'')

    extra_args = {} if extra_args is None else extra_args
    seed = extra_args.get("seed", None)
    sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max()
    noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=True) if noise_sampler is None else noise_sampler
    s_in = x.new_ones([x.shape[0]])

    model_sampling = model.inner_model.model_patcher.get_model_object('model_sampling')
    lambda_fn = partial(sigma_to_half_log_snr, model_sampling=model_sampling)
    sigmas = offset_first_sigma_for_snr(sigmas, model_sampling)
    s_noise = s_noise * getattr(model_sampling, "noise_scale", 1.0)

    old_denoised = None
    h, h_last = None, None

    for i in trange(len(sigmas) - 1, disable=disable):
        denoised = model(x, sigmas[i] * s_in, **extra_args)
        if callback is not None:

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Set solver_type to exactly 'midpoint' (default) or 'heun'
  2. Use a fixed combo input ['heun','midpoint'] in custom nodes rather than free text
  3. Trim/normalize strings when forwarding values from external config

Example fix

# before
sample_dpmpp_2m_sde(model, x, sigmas, solver_type='Heun')
# after
sample_dpmpp_2m_sde(model, x, sigmas, solver_type='heun')
Defensive patterns

Strategy: validation

Validate before calling

solver_type = solver_type.strip().lower()
assert solver_type in {'heun', 'midpoint'}, "solver_type must be 'heun' or 'midpoint'"

Type guard

def is_valid_2m_sde_solver(s: str) -> bool:
    return s in {'heun', 'midpoint'}

Prevention

When it happens

Trigger: Calling sample_dpmpp_2m_sde(..., solver_type='heun ') (trailing space), 'Heun' (case), or an invented value like 'midpoint2'. Custom nodes exposing a free-text field for solver_type instead of a fixed combo.

Common situations: API prompts edited by hand; combo values mismatched between frontend and backend after a custom node update; whitespace from JSON generation.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/be7b0383956d4149. Report an issue: GitHub.