{"record":{"id":"9bcbc863a916150d","repo":"Comfy-Org/ComfyUI","slug":"floats-strength-must-be-either-an-iterable-input-o","errorCode":null,"errorMessage":"floats_strength must be either an iterable input or a float, but was{type(floats_strength).__repr__}.","messagePattern":"floats_strength must be either an iterable input or a float, but was(.+?)\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"comfy_extras/nodes_hooks.py","lineNumber":584,"sourceCode":"\n    EXPERIMENTAL = True\n    RETURN_TYPES = (\"HOOK_KEYFRAMES\",)\n    RETURN_NAMES = (\"HOOK_KF\",)\n    CATEGORY = \"advanced/hooks/scheduling\"\n    FUNCTION = \"create_hook_keyframes\"\n\n    def create_hook_keyframes(self, floats_strength: Union[float, list[float]],\n                              start_percent: float, end_percent: float,\n                              prev_hook_kf: comfy.hooks.HookKeyframeGroup=None, print_keyframes=False):\n        if prev_hook_kf is None:\n            prev_hook_kf = comfy.hooks.HookKeyframeGroup()\n        prev_hook_kf = prev_hook_kf.clone()\n        if type(floats_strength) in (float, int):\n            floats_strength = [float(floats_strength)]\n        elif isinstance(floats_strength, Iterable):\n            pass\n        else:\n            raise Exception(f\"floats_strength must be either an iterable input or a float, but was{type(floats_strength).__repr__}.\")\n        percents = comfy.hooks.InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(floats_strength),\n                                                               method=comfy.hooks.InterpolationMethod.LINEAR)\n\n        is_first = True\n        for percent, strength in zip(percents, floats_strength):\n            guarantee_steps = 0\n            if is_first:\n                guarantee_steps = 1\n                is_first = False\n            prev_hook_kf.add(comfy.hooks.HookKeyframe(strength=strength, start_percent=percent, guarantee_steps=guarantee_steps))\n            if print_keyframes:\n                logging.info(f\"Hook Keyframe - start_percent:{percent} = {strength}\")\n        return (prev_hook_kf,)\n#------------------------------------------\n###########################################\n\n\nclass SetModelHooksOnCond:","sourceCodeStart":566,"sourceCodeEnd":602,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_extras/nodes_hooks.py#L566-L602","documentation":"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.","triggerScenarios":"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.","commonSituations":"Custom nodes that reuse create_hook_keyframes with unvalidated upstream values; feeding tensor data from math nodes that output tensors instead of floats.","solutions":["Pass a plain Python float (e.g. 1.0) or a list of floats like [1.0, 0.8, 0.5].","Convert upstream values before the call: float(x) for scalars, [float(v) for v in x] for sequences.","If the value comes from a custom node output, fix that node to emit FLOAT, not tensor/string."],"exampleFix":"// before\nstrength = tensor_mean  # torch tensor -> raises\ncreate_hook_keyframes(strength, 0.0, 1.0)\n\n// after\nstrength = float(tensor_mean.item())\ncreate_hook_keyframes(strength, 0.0, 1.0)","handlingStrategy":"type-guard","validationCode":"from collections.abc import Iterable\nstrength = float(strength) if isinstance(strength, (int, float)) else [float(v) for v in strength] if isinstance(strength, Iterable) else None\nif strength is None:\n    raise TypeError(f\"floats_strength has unsupported type {type(strength).__name__}\")","typeGuard":"def is_valid_strength(x) -> bool:\n    return isinstance(x, (int, float)) or (isinstance(x, (list, tuple)) and all(isinstance(v, (int, float)) for v in x))","tryCatchPattern":"try:\n    kfs = create_hook_keyframes(strength, start, end)\nexcept Exception as e:\n    if \"floats_strength\" in str(e):\n        kfs = create_hook_keyframes(float(strength), start, end)  # coerce and retry once\n    else:\n        raise","preventionTips":["Always convert upstream values to plain Python floats before calling hook keyframe APIs.","Custom nodes should validate Autogrow strength inputs are FLOAT before forwarding.","Remember numpy scalars and tensors are rejected — call .item()/float() first."],"tags":["type-error","hooks","controlnet","strength","validation"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}