{"record":{"id":"2a2d7cd671ec010f","repo":"Comfy-Org/ComfyUI","slug":"keyframe-times-cannot-be-negative-got-times-0","errorCode":null,"errorMessage":"Keyframe times cannot be negative; got {times[0]}.","messagePattern":"Keyframe times cannot be negative; got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_bfl.py","lineNumber":1072,"sourceCode":"\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\n    @classmethod\n    def common_inputs(cls) -> list:\n        return [\n            IO.Combo.Input(\n                \"aspect_ratio\",\n                options=_FLUX3_ASPECT_RATIOS,","sourceCodeStart":1054,"sourceCodeEnd":1090,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_bfl.py#L1054-L1090","documentation":"The first keyframe time defines the clip start offset and cannot be negative; times[0] < 0 is rejected. Negative lead-in times have no meaning in the FLUX 3 timeline model.","triggerScenarios":"Passing a leading negative value such as '-2, 3, 7'; typically from offset math or sign typos.","commonSituations":"Computing times relative to an event that starts before the clip; copy-paste sign errors.","solutions":["Clamp the first time to >= 0: times[0] = max(times[0], 0.0).","Re-base offsets so the earliest keyframe is at 0.","Check sign conventions in upstream time computation."],"exampleFix":"# before\nkeyframe_times = \"-2, 3, 7\"  # ValueError\n\n# after\ntimes = [max(0.0, t) for t in times]\nkeyframe_times = \", \".join(str(t) for t in times)","handlingStrategy":"validation","validationCode":"times = [float(p) for p in value.split(\",\")]\nassert times[0] >= 0, f\"negative first keyframe {times[0]}\"","typeGuard":"def first_time_non_negative(times: list[float]) -> bool:\n    return times[0] >= 0","tryCatchPattern":null,"preventionTips":["Clamp computed offsets with max(0.0, t).","Re-base offsets so the earliest keyframe is 0.","Review sign conventions in offset math."],"tags":["bfl","flux3","keyframes","negative","input-validation"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}