{"record":{"id":"5c1c974b7bb39f81","repo":"Comfy-Org/ComfyUI","slug":"keyframe-times-must-be-numbers-in-seconds-comma-s","errorCode":null,"errorMessage":"Keyframe times must be numbers in seconds, comma-separated; got '{value}'.","messagePattern":"Keyframe times must be numbers in seconds, comma-separated; got '(.+?)'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_bfl.py","lineNumber":1066,"sourceCode":"            flat.append(tensor)\n    if len(flat) > _FLUX3_MAX_IMAGES:\n        raise ValueError(f\"FLUX 3 supports at most {_FLUX3_MAX_IMAGES} {field_name}, got {len(flat)}.\")\n    for tensor in flat:\n        _flux3_validate_image(tensor)\n    return flat\n\n\ndef _flux3_parse_times(value: str, image_count: int, duration: int | str) -> list[float]:\n    \"\"\"Parse one keyframe time in seconds per image: increasing, inside the clip.\"\"\"\n    parts = [part.strip() for part in value.split(\",\") if part.strip()]\n    if len(parts) != image_count:\n        raise ValueError(\n            f\"Give one time per keyframe image: got {len(parts)} time(s) for {image_count} image(s).\"\n        )\n    try:\n        times = [float(part) for part in parts]\n    except ValueError as exc:\n        raise ValueError(f\"Keyframe times must be numbers in seconds, comma-separated; got '{value}'.\") from exc\n    if not all(math.isfinite(time) for time in times):\n        raise ValueError(f\"Keyframe times must be finite numbers in seconds; got '{value}'.\")\n    if any(later <= earlier for earlier, later in zip(times, times[1:])):\n        raise ValueError(f\"Keyframe times must increase; got {times}.\")\n    if times[0] < 0:\n        raise ValueError(f\"Keyframe times cannot be negative; got {times[0]}.\")\n    cap = _FLUX3_MAX_DURATION if duration == \"auto\" else int(duration)\n    if times[-1] > cap:\n        raise ValueError(f\"Keyframe time {times[-1]}s is past the end of a {cap}s clip.\")\n    return times\n\n\nclass Flux3VideoNodeBase(IO.ComfyNode):\n    \"\"\"Shared widgets, request plumbing and polling for the FLUX 3 generation modes.\"\"\"\n\n    RATE_HD: float\n    RATE_FHD: float\n","sourceCodeStart":1048,"sourceCodeEnd":1084,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_bfl.py#L1048-L1084","documentation":"Each comma-separated keyframe time must parse as a float. float(part) failing (letters, malformed numbers, locale decimal commas like '2,5' surviving a split) raises this ValueError chained from the original parse error.","triggerScenarios":"Passing times like 'one,two', '3..5', or locale-formatted values; also '2,5 s' style strings with units or stray characters.","commonSituations":"Hand-typed widget values; localized number formatting; stray units ('s', 'sec') pasted from documentation examples.","solutions":["Use plain dot-decimal seconds: '0, 2.5, 5.0'.","Strip units and spaces from generated time strings.","Generate the string programmatically: ','.join(f'{t}' for t in times)."],"exampleFix":"# before\nkeyframe_times = \"0s, 5s\"  # ValueError: not numbers\n\n# after\nkeyframe_times = \"0, 5\"","handlingStrategy":"try-catch","validationCode":"try:\n    [float(p) for p in value.split(\",\")]\nexcept ValueError:\n    raise ValueError(f\"times must be numeric: {value!r}\")","typeGuard":"def times_parseable(value: str) -> bool:\n    try:\n        return all(True for _ in (float(p) for p in value.split(\",\")))\n    except ValueError:\n        return False","tryCatchPattern":"try:\n    times = _flux3_parse_times(value, n, duration)\nexcept ValueError as e:\n    if \"must be numbers\" in str(e):\n        times = _flux3_parse_times(sanitize(value), n, duration)","preventionTips":["Use dot-decimal seconds only.","Strip units and spaces when building strings programmatically.","Avoid locale-formatted decimal commas."],"tags":["bfl","flux3","keyframes","parsing","locale"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}