Comfy-Org/ComfyUI · error · ValueError

order should be 2 or 3

Error message

order should be 2 or 3

What it means

Raised by DPMSolver.dpm_solver_adaptive when the requested multistep order is not 2 or 3. DPM-Solver-12 and DPM-Solver-23 are the only adaptive variants implemented (order 2 = 1-2 pair, order 3 = 2-3 pair); the adaptive error estimator and PID step controller are only coded for those two.

Source

Thrown at comfy/k_diffusion/sampling.py:569

            denoised = x - self.sigma(t) * eps
            if self.info_callback is not None:
                self.info_callback({'x': x, 'i': i, 't': ts[i], 't_up': t, 'denoised': denoised})

            if orders[i] == 1:
                x, eps_cache = self.dpm_solver_1_step(x, t, t_next_, eps_cache=eps_cache)
            elif orders[i] == 2:
                x, eps_cache = self.dpm_solver_2_step(x, t, t_next_, eps_cache=eps_cache)
            else:
                x, eps_cache = self.dpm_solver_3_step(x, t, t_next_, eps_cache=eps_cache)

            x = x + su * s_noise * noise_sampler(self.sigma(t), self.sigma(t_next))

        return x

    def dpm_solver_adaptive(self, x, t_start, t_end, order=3, rtol=0.05, atol=0.0078, h_init=0.05, pcoeff=0., icoeff=1., dcoeff=0., accept_safety=0.81, eta=0., s_noise=1., noise_sampler=None):
        noise_sampler = default_noise_sampler(x, seed=self.extra_args.get("seed", None)) if noise_sampler is None else noise_sampler
        if order not in {2, 3}:
            raise ValueError('order should be 2 or 3')
        forward = t_end > t_start
        if not forward and eta:
            raise ValueError('eta must be 0 for reverse sampling')
        h_init = abs(h_init) * (1 if forward else -1)
        atol = torch.tensor(atol)
        rtol = torch.tensor(rtol)
        s = t_start
        x_prev = x
        accept = True
        pid = PIDStepSizeController(h_init, pcoeff, icoeff, dcoeff, 1.5 if eta else order, accept_safety)
        info = {'steps': 0, 'nfe': 0, 'n_accept': 0, 'n_reject': 0}

        while s < t_end - 1e-5 if forward else s > t_end + 1e-5:
            eps_cache = {}
            t = torch.minimum(t_end, s + pid.h) if forward else torch.maximum(t_end, s + pid.h)
            if eta:
                sd, su = get_ancestral_step(self.sigma(s), self.sigma(t), eta)
                t_ = torch.minimum(t_end, self.t(sd))

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Use order=3 (default, DPM-Solver-23) or order=2 (DPM-Solver-12)
  2. Restrict the node widget/combo for sample_dpm_adaptive to [2,3]
  3. For other orders switch to a fixed-step sampler like sample_dpmpp_2m or sample_lms

Example fix

# before
sample_dpm_adaptive(model, x, 0.03, 14.6, order=4)
# after
sample_dpm_adaptive(model, x, 0.03, 14.6, order=3)
Defensive patterns

Strategy: validation

Validate before calling

assert order in (2, 3), 'sample_dpm_adaptive order must be 2 or 3'
sample_dpm_adaptive(model, x, sigma_min, sigma_max, order=order)

Type guard

def is_valid_adaptive_order(order) -> bool:
    return order in (2, 3)

Prevention

When it happens

Trigger: Calling sample_dpm_adaptive(..., order=1) or order=4/5 through a custom node or script. The check is `order not in {2, 3}` before any stepping begins.

Common situations: Custom nodes exposing an order widget for dpm_solver_adaptive with values copied from the LMS sampler (1-4); API workflows edited by hand with an invalid order value.

Related errors


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