{"record":{"id":"a0a29ce8204445ee","repo":"mifi/lossless-cut","slug":"failed-to-find-any-prev-frame","errorCode":null,"errorMessage":"Failed to find any prev frame","messagePattern":"Failed to find any prev frame","errorType":"exception","errorClass":"UserFacingError","httpStatus":null,"severity":"error","filePath":"src/renderer/src/ffmpeg.ts","lineNumber":174,"sourceCode":"    index = frames.findIndex((f) => f.keyframe && f.time >= cutTime - sigma);\n    if (index === -1) throw new UserFacingError(i18n.t('Failed to find next keyframe'));\n    if (index >= frames.length - 1) throw new UserFacingError(i18n.t('We are on the last frame'));\n    const { time } = frames[index]!;\n    if (isCloseTo(time, cutTime)) {\n      return undefined; // Already on keyframe, no need to modify cut time\n    }\n    return time;\n  }\n\n  const findReverseIndex = <T>(arr: T[], cb: (value: T, i: number, obj: T[]) => unknown) => {\n    // eslint-disable-next-line unicorn/no-array-callback-reference\n    const ret = [...arr].reverse().findIndex(cb);\n    if (ret === -1) return -1;\n    return arr.length - 1 - ret;\n  };\n\n  index = findReverseIndex(frames, (f) => f.time <= cutTime + sigma);\n  if (index === -1) throw new UserFacingError(i18n.t('Failed to find any prev frame'));\n  if (index === 0) throw new UserFacingError(i18n.t('We are on the first frame'));\n\n  if (index === frames.length - 1) {\n    // Last frame of video, no need to modify cut time\n    return undefined;\n  }\n  if (frames[index + 1]!.keyframe) {\n    // Already on frame before keyframe, no need to modify cut time\n    return undefined;\n  }\n\n  // We are not on a frame before keyframe, look for preceding keyframe instead\n  index = findReverseIndex(frames, (f) => f.keyframe && f.time <= cutTime + sigma);\n  if (index === -1) throw new UserFacingError(i18n.t('Failed to find any prev keyframe'));\n  if (index === 0) throw new UserFacingError(i18n.t('We are on the first keyframe'));\n\n  // Use frame before the found keyframe\n  return frames[index - 1]!.time;","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/mifi/lossless-cut/blob/3b9a59c288bf6e11076b583c932cfa48ddab3b02/src/renderer/src/ffmpeg.ts#L156-L192","documentation":"Thrown by getSafeCutTime() in the non-next (previous) branch when findReverseIndex returns -1, i.e. no frame in the list has a time <= cutTime + sigma. The function needs the frame at or just before the cut to anchor a previous-keyframe search, so the absence of any preceding frame is fatal. Effectively the cut point lies before the first known frame.","triggerScenarios":"Calling getSafeCutTime(frames, cutTime, false) where cutTime is earlier than the earliest frame's time; a frames array that only covers a window strictly after the cut point; cutTime clamped/rounded to a value below the first frame timestamp.","commonSituations":"Probe window starts after the cut; negative or zero cutTime on a stream whose first frame time is positive (timestamp offset); cutting at the very start of a file where the frame list begins later than expected; misaligned time bases between the cut time and the frame probe.","solutions":["Ensure the frame probe window includes frames at or before cutTime (probe from 0 or extend the window backward).","Clamp cutTime to >= the first frame's time before calling getSafeCutTime.","If the cut is at the very start, short-circuit: no previous-keyframe adjustment is needed.","Verify timebase/timestamp consistency between the cut clock and the frame probe clock."],"exampleFix":"// before\nconst t = getSafeCutTime(frames, cutTime, false);\n\n// after\nconst firstFrameTime = frames[0]?.time ?? 0;\nconst clamped = Math.max(cutTime, firstFrameTime);\nconst t = getSafeCutTime(frames, clamped, false);","handlingStrategy":"validation","validationCode":"const sigma = 0.01;\nconst firstFrameTime = frames[0]?.time ?? 0;\nif (cutTime < firstFrameTime - sigma) {\n  // cut is before any known frame; clamp or skip\n  return undefined;\n}","typeGuard":null,"tryCatchPattern":"try {\n  return getSafeCutTime(frames, cutTime, false);\n} catch (err) {\n  if (err instanceof UserFacingError && /any prev frame/.test(err.message)) {\n    return undefined;\n  }\n  throw err;\n}","preventionTips":["Probe frames from time 0 so the list includes frames at/before the cut.","Clamp cutTime to >= the first frame's timestamp before calling getSafeCutTime.","Ensure the cut clock and the frame probe share the same time base."],"tags":["ffmpeg","keyframe","smart-cut","frames","prev-mode"],"backgroundTag":null,"analyzedSha":"3b9a59c288bf6e11076b583c932cfa48ddab3b02","analyzedAt":"2026-08-12T20:54:25.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}