Comfy-Org/ComfyUI · error · Exception

floats_strength must be either an iterable input or a float,

Error message

floats_strength must be either an iterable input or a float, but was{type(floats_strength).__repr__}.

What it means

Raised by create_hook_keyframes() in the ControlNet-style hook keyframe nodes: floats_strength must be a float/int (wrapped into a 1-element list) or an iterable of floats (one strength per keyframe). Anything else — a tensor, a string, None — falls through both branches and raises. Note the guard is type(floats_strength) in (float, int), so bool passes as int and numpy scalars fail.

Source

Thrown at comfy_extras/nodes_hooks.py:584

    EXPERIMENTAL = True
    RETURN_TYPES = ("HOOK_KEYFRAMES",)
    RETURN_NAMES = ("HOOK_KF",)
    CATEGORY = "advanced/hooks/scheduling"
    FUNCTION = "create_hook_keyframes"

    def create_hook_keyframes(self, floats_strength: Union[float, list[float]],
                              start_percent: float, end_percent: float,
                              prev_hook_kf: comfy.hooks.HookKeyframeGroup=None, print_keyframes=False):
        if prev_hook_kf is None:
            prev_hook_kf = comfy.hooks.HookKeyframeGroup()
        prev_hook_kf = prev_hook_kf.clone()
        if type(floats_strength) in (float, int):
            floats_strength = [float(floats_strength)]
        elif isinstance(floats_strength, Iterable):
            pass
        else:
            raise Exception(f"floats_strength must be either an iterable input or a float, but was{type(floats_strength).__repr__}.")
        percents = comfy.hooks.InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(floats_strength),
                                                               method=comfy.hooks.InterpolationMethod.LINEAR)

        is_first = True
        for percent, strength in zip(percents, floats_strength):
            guarantee_steps = 0
            if is_first:
                guarantee_steps = 1
                is_first = False
            prev_hook_kf.add(comfy.hooks.HookKeyframe(strength=strength, start_percent=percent, guarantee_steps=guarantee_steps))
            if print_keyframes:
                logging.info(f"Hook Keyframe - start_percent:{percent} = {strength}")
        return (prev_hook_kf,)
#------------------------------------------
###########################################


class SetModelHooksOnCond:

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Pass a plain Python float (e.g. 1.0) or a list of floats like [1.0, 0.8, 0.5].
  2. Convert upstream values before the call: float(x) for scalars, [float(v) for v in x] for sequences.
  3. If the value comes from a custom node output, fix that node to emit FLOAT, not tensor/string.

Example fix

// before
strength = tensor_mean  # torch tensor -> raises
create_hook_keyframes(strength, 0.0, 1.0)

// after
strength = float(tensor_mean.item())
create_hook_keyframes(strength, 0.0, 1.0)
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Iterable
strength = float(strength) if isinstance(strength, (int, float)) else [float(v) for v in strength] if isinstance(strength, Iterable) else None
if strength is None:
    raise TypeError(f"floats_strength has unsupported type {type(strength).__name__}")

Type guard

def is_valid_strength(x) -> bool:
    return isinstance(x, (int, float)) or (isinstance(x, (list, tuple)) and all(isinstance(v, (int, float)) for v in x))

Try / catch

try:
    kfs = create_hook_keyframes(strength, start, end)
except Exception as e:
    if "floats_strength" in str(e):
        kfs = create_hook_keyframes(float(strength), start, end)  # coerce and retry once
    else:
        raise

Prevention

When it happens

Trigger: Connecting a non-float source to the strength input (e.g. a STRING node, a CONDITIONING, or a torch tensor from a custom node); passing a numpy float32 scalar (not a Python float and not Iterable); passing None because the optional input was left unconnected and forwarded as-is by custom glue code.

Common situations: Custom nodes that reuse create_hook_keyframes with unvalidated upstream values; feeding tensor data from math nodes that output tensors instead of floats.

Related errors


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