remotion-dev/remotion · error · Error

No sample found

Error message

No sample found

What it means

Thrown by findKeyframeBeforeTime when no SamplePosition in the provided list satisfies the criteria: it must be a keyframe (sample.isKeyframe) and its composition or decode time in seconds must be <= the requested time. After the loop, videoSample stays null, which means there is no keyframe at or before the seek target. This usually indicates the sample table does not yet cover the requested time, or the file has no keyframes flagged in the time window.

Source

Thrown at packages/media-parser/src/containers/iso-base-media/find-keyframe-before-time.ts:43

		const ctsInSeconds = sample.timestamp / timescale + startInSeconds;
		const dtsInSeconds = sample.decodingTimestamp / timescale + startInSeconds;

		if (!sample.isKeyframe) {
			continue;
		}

		if (!(ctsInSeconds <= time || dtsInSeconds <= time)) {
			continue;
		}

		if (videoByte <= sample.offset) {
			videoByte = sample.offset;
			videoSample = sample;
		}
	}

	if (!videoSample) {
		throw new Error('No sample found');
	}

	const mediaSection = mediaSections.find(
		(section) =>
			videoSample.offset >= section.start &&
			videoSample.offset < section.start + section.size,
	);

	if (!mediaSection) {
		Log.trace(
			logLevel,
			'Found a sample, but the offset has not yet been marked as a video section yet. Not yet able to seek, but probably once we have started reading the next box.',
			videoSample,
		);
		return null;
	}

	return videoSample;

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure seek targets are >= the track's startInSeconds; clamp negative or pre-roll seeks to that value.
  2. If the file has no stss (sync samples) box, re-mux so every I-frame is marked: `ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4`.
  3. For fragmented streams, wait for more fragments (this is often transient; retry after the next moof arrives).
  4. Validate that samplePositions passed in actually contain at least one keyframe before calling findKeyframeBeforeTime.

Example fix

// before
const kf = findKeyframeBeforeTime({ samplePositions, time, timescale, mediaSections, logLevel, startInSeconds });

// after
const hasKeyframe = samplePositions.some((s) => s.isKeyframe);
if (!hasKeyframe) {
  return null; // not seekable, caller should fall back to linear scan
}
const kf = findKeyframeBeforeTime({
  samplePositions,
  time: Math.max(time, startInSeconds),
  timescale, mediaSections, logLevel, startInSeconds,
});
Defensive patterns

Strategy: validation

Validate before calling

// Validate there is at least one usable keyframe before calling findKeyframeBeforeTime
import type {SamplePosition} from '../../get-sample-positions';
function findableKeyframe(samples: SamplePosition[], time: number, timescale: number, startInSeconds: number): boolean {
  return samples.some((s) => {
    if (!s.isKeyframe) return false;
    const cts = s.timestamp / timescale + startInSeconds;
    const dts = s.decodingTimestamp / timescale + startInSeconds;
    return cts <= time || dts <= time;
  });
}

Type guard

import type {SamplePosition} from '../../get-sample-positions';
function hasAnyKeyframe(samples: SamplePosition[]): boolean {
  return samples.length > 0 && samples.some((s) => s.isKeyframe);
}

Try / catch

try {
  const kf = findKeyframeBeforeTime({ samplePositions, time, timescale, mediaSections, logLevel, startInSeconds });
} catch (err) {
  if (/No sample found/i.test(String(err?.message))) {
    // Either wait for more fragments or fall back to a linear scan from byte 0
    return { type: 'valid-but-must-wait' } as const;
  }
  throw err;
}

Prevention

When it happens

Trigger: Called during seek resolution (progressive or fragmented MP4) when a time falls before the first keyframe, when all keyframes in the available samples have timestamps after the requested time, or when stss (sync sample table) was missing so no sample.isKeyframe is ever true. Also reachable if startInSeconds is set incorrectly, shifting times forward.

Common situations: Seeking to time 0 or a very early time in a stream whose first keyframe sits at a positive offset (edit-list shifts). Live/DASH fragments where the first fragment's tfdt base pushes times above zero. Files with no stss box (parser falls back to marking nothing as keyframe). Requesting a seek beyond the buffered/downloaded range.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/66fd10fe2414dae9. Report an issue: GitHub.