mifi/lossless-cut · error · UserFacingError

Failed to find any prev frame

Error message

Failed to find any prev frame

What it means

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.

Solutions

  1. Ensure the frame probe window includes frames at or before cutTime (probe from 0 or extend the window backward).
  2. Clamp cutTime to >= the first frame's time before calling getSafeCutTime.
  3. If the cut is at the very start, short-circuit: no previous-keyframe adjustment is needed.
  4. Verify timebase/timestamp consistency between the cut clock and the frame probe clock.

Example fix

// before
const t = getSafeCutTime(frames, cutTime, false);

// after
const firstFrameTime = frames[0]?.time ?? 0;
const clamped = Math.max(cutTime, firstFrameTime);
const t = getSafeCutTime(frames, clamped, false);
Defensive patterns

Strategy: validation

Validate before calling

const sigma = 0.01;
const firstFrameTime = frames[0]?.time ?? 0;
if (cutTime < firstFrameTime - sigma) {
  // cut is before any known frame; clamp or skip
  return undefined;
}

Try / catch

try {
  return getSafeCutTime(frames, cutTime, false);
} catch (err) {
  if (err instanceof UserFacingError && /any prev frame/.test(err.message)) {
    return undefined;
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mifi/lossless-cut@3b9a59c288 (2026-08-12). Data as JSON: /api/errors/a0a29ce8204445ee. Report an issue: GitHub.

Appendix: source

Thrown at src/renderer/src/ffmpeg.ts:174

    index = frames.findIndex((f) => f.keyframe && f.time >= cutTime - sigma);
    if (index === -1) throw new UserFacingError(i18n.t('Failed to find next keyframe'));
    if (index >= frames.length - 1) throw new UserFacingError(i18n.t('We are on the last frame'));
    const { time } = frames[index]!;
    if (isCloseTo(time, cutTime)) {
      return undefined; // Already on keyframe, no need to modify cut time
    }
    return time;
  }

  const findReverseIndex = <T>(arr: T[], cb: (value: T, i: number, obj: T[]) => unknown) => {
    // eslint-disable-next-line unicorn/no-array-callback-reference
    const ret = [...arr].reverse().findIndex(cb);
    if (ret === -1) return -1;
    return arr.length - 1 - ret;
  };

  index = findReverseIndex(frames, (f) => f.time <= cutTime + sigma);
  if (index === -1) throw new UserFacingError(i18n.t('Failed to find any prev frame'));
  if (index === 0) throw new UserFacingError(i18n.t('We are on the first frame'));

  if (index === frames.length - 1) {
    // Last frame of video, no need to modify cut time
    return undefined;
  }
  if (frames[index + 1]!.keyframe) {
    // Already on frame before keyframe, no need to modify cut time
    return undefined;
  }

  // We are not on a frame before keyframe, look for preceding keyframe instead
  index = findReverseIndex(frames, (f) => f.keyframe && f.time <= cutTime + sigma);
  if (index === -1) throw new UserFacingError(i18n.t('Failed to find any prev keyframe'));
  if (index === 0) throw new UserFacingError(i18n.t('We are on the first keyframe'));

  // Use frame before the found keyframe
  return frames[index - 1]!.time;

View on GitHub (pinned to 3b9a59c288)