{"record":{"id":"be7b0383956d4149","repo":"Comfy-Org/ComfyUI","slug":"solver-type-must-be-heun-or-midpoint","errorCode":null,"errorMessage":"solver_type must be 'heun' or 'midpoint'","messagePattern":"solver_type must be 'heun' or 'midpoint'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy/k_diffusion/sampling.py","lineNumber":828,"sourceCode":"        if old_denoised is None or sigmas[i + 1] == 0:\n            x = (sigma_fn(t_next) / sigma_fn(t)) * x - (-h).expm1() * denoised\n        else:\n            h_last = t - t_fn(sigmas[i - 1])\n            r = h_last / h\n            denoised_d = (1 + 1 / (2 * r)) * denoised - (1 / (2 * r)) * old_denoised\n            x = (sigma_fn(t_next) / sigma_fn(t)) * x - (-h).expm1() * denoised_d\n        old_denoised = denoised\n    return x\n\n\n@torch.no_grad()\ndef 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'):\n    \"\"\"DPM-Solver++(2M) SDE.\"\"\"\n    if len(sigmas) <= 1:\n        return x\n\n    if solver_type not in {'heun', 'midpoint'}:\n        raise ValueError('solver_type must be \\'heun\\' or \\'midpoint\\'')\n\n    extra_args = {} if extra_args is None else extra_args\n    seed = extra_args.get(\"seed\", None)\n    sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max()\n    noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=True) if noise_sampler is None else noise_sampler\n    s_in = x.new_ones([x.shape[0]])\n\n    model_sampling = model.inner_model.model_patcher.get_model_object('model_sampling')\n    lambda_fn = partial(sigma_to_half_log_snr, model_sampling=model_sampling)\n    sigmas = offset_first_sigma_for_snr(sigmas, model_sampling)\n    s_noise = s_noise * getattr(model_sampling, \"noise_scale\", 1.0)\n\n    old_denoised = None\n    h, h_last = None, None\n\n    for i in trange(len(sigmas) - 1, disable=disable):\n        denoised = model(x, sigmas[i] * s_in, **extra_args)\n        if callback is not None:","sourceCodeStart":810,"sourceCodeEnd":846,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy/k_diffusion/sampling.py#L810-L846","documentation":"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.","triggerScenarios":"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.","commonSituations":"API prompts edited by hand; combo values mismatched between frontend and backend after a custom node update; whitespace from JSON generation.","solutions":["Set solver_type to exactly 'midpoint' (default) or 'heun'","Use a fixed combo input ['heun','midpoint'] in custom nodes rather than free text","Trim/normalize strings when forwarding values from external config"],"exampleFix":"# before\nsample_dpmpp_2m_sde(model, x, sigmas, solver_type='Heun')\n# after\nsample_dpmpp_2m_sde(model, x, sigmas, solver_type='heun')","handlingStrategy":"validation","validationCode":"solver_type = solver_type.strip().lower()\nassert solver_type in {'heun', 'midpoint'}, \"solver_type must be 'heun' or 'midpoint'\"","typeGuard":"def is_valid_2m_sde_solver(s: str) -> bool:\n    return s in {'heun', 'midpoint'}","tryCatchPattern":null,"preventionTips":["Use a fixed combo ['heun','midpoint'] for dpmpp_2m_sde","Normalize solver strings from external config before dispatch"],"tags":["sampling","dpmpp","sde","solver-type","validation"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}