{"record":{"id":"17ca947d65e9193d","repo":"mifi/lossless-cut","slug":"failed-to-find-any-prev-keyframe","errorCode":null,"errorMessage":"Failed to find any prev keyframe","messagePattern":"Failed to find any prev keyframe","errorType":"exception","errorClass":"UserFacingError","httpStatus":null,"severity":"error","filePath":"src/renderer/src/ffmpeg.ts","lineNumber":188,"sourceCode":"    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;\n}\n\nexport function findNearestKeyFrameTime({ frames, time, direction }: { frames: Frame[], time: number, direction: number }) {\n  const keyframes = frames.filter((f) => f.keyframe && (direction > 0 ? f.time >= time : f.time <= time));\n  if (keyframes.length === 0) return undefined;\n  const nearestKeyFrame = sortBy(keyframes, (keyframe) => (direction > 0 ? keyframe.time - time : time - keyframe.time))[0];\n  if (!nearestKeyFrame) return undefined;\n  return nearestKeyFrame.time;\n}\n\nexport function tryMapChaptersToEdl(chapters: FFprobeChapter[]) {\n  try {\n    return chapters.flatMap((chapter) => {\n      const start = parseFloat(chapter.start_time);","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/mifi/lossless-cut/blob/3b9a59c288bf6e11076b583c932cfa48ddab3b02/src/renderer/src/ffmpeg.ts#L170-L206","documentation":"Thrown by getSafeCutTime() (previous branch) after it has confirmed the index frame's successor is not a keyframe, when the reverse search for a preceding keyframe (time <= cutTime + sigma) yields -1. The function needs a previous keyframe to reposition the cut onto a safe boundary, and none exists earlier in the frame list. This means there is no keyframe at or before the cut at all.","triggerScenarios":"Calling getSafeCutTime in prev mode where the only keyframe in the list is the one at/after the cut; the frame window was probed starting after the first keyframe; a stream where the very first keyframe sits after the cut point.","commonSituations":"Cutting at the absolute start of a file (the first keyframe is the only one and it is at/after the cut); a frame probe window that excluded the stream's first keyframe; damaged streams missing their initial IDR frame.","solutions":["Extend the keyframe/frame probe backward to include the stream's first keyframe (probe from time 0).","If the cut is at the file start, skip smart-cut alignment (cut is already at a safe boundary).","Re-encode the source to guarantee a keyframe at position 0 (-force_key_frames).","Fall back to lossless cut at the requested time when no preceding keyframe exists."],"exampleFix":"// before\nconst t = getSafeCutTime(frames, cutTime, false);\n\n// after\nconst hasPrevKeyframe = frames.some((f) => f.keyframe && f.time <= cutTime + 0.01);\nconst t = hasPrevKeyframe ? getSafeCutTime(frames, cutTime, false) : cutTime;","handlingStrategy":"validation","validationCode":"const sigma = 0.01;\nconst hasPrevKeyframe = frames.some((f) => f.keyframe && f.time <= cutTime + sigma);\nif (!hasPrevKeyframe) {\n  // no earlier keyframe; cannot align backward\n  return undefined;\n}","typeGuard":null,"tryCatchPattern":"try {\n  return getSafeCutTime(frames, cutTime, false);\n} catch (err) {\n  if (err instanceof UserFacingError && /any prev keyframe/.test(err.message)) {\n    return cutTime;\n  }\n  throw err;\n}","preventionTips":["Include the stream's first keyframe in the probe window (start from 0).","Skip alignment when cutting at the file start (already at a safe boundary).","Re-encode with a guaranteed keyframe at position 0 if backward cuts are required."],"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"}