mifi/lossless-cut · error · UserFacingError

No valid segments found

Error message

No valid segments found

What it means

Thrown by loadCutSegments() when the segments array passed in has length 0. The function exists to load/import a set of cut segments into the timeline, and an empty input would wipe the current segment list without adding anything. It is an explicit precondition before the maxSegmentsAllowed check and before any state mutation.

Source

Thrown at src/renderer/src/hooks/useSegments.tsx:170

  const clearSegments = useCallback(() => {
    clearSegColorCounter();
    safeSetCutSegments([]);
  }, [clearSegColorCounter, safeSetCutSegments]);

  const shuffleSegments = useCallback(() => safeSetCutSegments((existingSegments) => [
    ...existingSegments.filter((s) => !s.selected),
    ...shuffleArray(existingSegments.filter((s) => s.selected)),
  ]), [safeSetCutSegments]);

  // todo combine with safeSetCutSegments?
  const loadCutSegments = useCallback(({ segments, append, clampDuration, getNextCurrentSegIndex }: {
    segments: SegmentBase[],
    append: boolean,
    clampDuration?: number | undefined,
    getNextCurrentSegIndex?: (newEdl: SegmentBase[]) => number,
  }) => {
    if (segments.length === 0) throw new UserFacingError(i18n.t('No valid segments found'));

    if (segments.length > maxSegmentsAllowed) throw new UserFacingError(i18n.t('Tried to create too many segments (max {{maxSegmentsAllowed}}.)', { maxSegmentsAllowed }));

    if (!append) clearSegColorCounter();

    safeSetCutSegments((existingSegments) => {
      const needToAppend = append && !isInitialSegment(existingSegments);
      let newSegments = segments.map((segment, i) => createIndexedSegment({ segment, incrementCount: needToAppend || i > 0 }));
      if (needToAppend) newSegments = [...existingSegments, ...newSegments];
      if (getNextCurrentSegIndex) setCurrentSegIndex(getNextCurrentSegIndex(newSegments));
      return newSegments;
    }, clampDuration);
  }, [clearSegColorCounter, createIndexedSegment, safeSetCutSegments]);

  const detectSegments = useCallback(async ({ name, workingText, errorText, fn }: {
    name: string,
    workingText: string,
    errorText: string,

View on GitHub (pinned to 3b9a59c288)

Solutions

  1. Check segments.length > 0 before calling loadCutSegments; skip the call if empty.
  2. Investigate why the upstream parser produced zero segments (see related parse errors).
  3. Show the user 'no segments to import' instead of attempting the load.
  4. When appending, guard the empty case so an empty import does not replace existing segments.

Example fix

// before
loadCutSegments({ segments, append });

// after
if (segments.length === 0) {
  toast.info('No segments to import');
  return;
}
loadCutSegments({ segments, append });
Defensive patterns

Strategy: validation

Validate before calling

// Guard the load call against an empty segment list
if (!Array.isArray(segments) || segments.length === 0) {
  toast.info('No segments to import');
  return;
}
loadCutSegments({ segments, append });

Type guard

const hasSegments = (segs: unknown): segs is SegmentBase[] => Array.isArray(segs) && segs.length > 0;

Try / catch

try {
  loadCutSegments({ segments, append });
} catch (err) {
  if (err instanceof UserFacingError && /No valid segments/.test(err.message)) {
    showError('The imported file produced no segments.');
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling loadCutSegments({ segments: [], ... }) from an EDL/CSV import that produced zero segments; a parser returned an empty array (e.g. an EDL with no rows that passed earlier guards); a programmatic caller passing an uninitialised array.

Common situations: An imported file parsed to no usable segments (empty cut list); a copy/move operation that filtered out all segments; a bug where a parser returns [] unexpectedly; selecting nothing and triggering a load.

Related errors


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