remotion-dev/remotion · error

has no bytes

Error message

has no bytes

What it means

expectSegment throws 'has no bytes' if iterator.bytesRemaining()===0 at entry. The function is called repeatedly by parseWebm to read the next top-level element; reaching it with zero bytes means the continuation loop was not stopped at end-of-stream. The branch is a defensive guard for a state-machine edge.

Source

Thrown at packages/media-parser/src/containers/webm/segments.ts:35

export type MatroskaSegment = PossibleEbml;

export type OnTrackEntrySegment = (trackEntry: TrackEntry) => void;

export const expectSegment = async ({
	statesForProcessing,
	isInsideSegment,
	iterator,
	logLevel,
	mediaSectionState,
}: {
	iterator: BufferIterator;
	logLevel: MediaParserLogLevel;
	statesForProcessing: WebmRequiredStatesForProcessing | null;
	isInsideSegment: SegmentSection | null;
	mediaSectionState: MediaSectionState | null;
}): Promise<MatroskaSegment | null> => {
	if (iterator.bytesRemaining() === 0) {
		throw new Error('has no bytes');
	}

	const offset = iterator.counter.getOffset();
	const {returnToCheckpoint} = iterator.startCheckpoint();
	const segmentId = iterator.getMatroskaSegmentId();

	if (segmentId === null) {
		returnToCheckpoint();
		return null;
	}

	const offsetBeforeVInt = iterator.counter.getOffset();
	const size = iterator.getVint();
	const offsetAfterVInt = iterator.counter.getOffset();

	if (size === null) {
		returnToCheckpoint();
		return null;

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. If using a custom reader, ensure bytesRemaining() returns 0 exactly when EOF is reached and that parseMedia's loop observes it.
  2. Re-mux the file to give the Segment a concrete size.
  3. Use the built-in webReader or fetchReader with a complete Blob instead.
  4. Try Mediabunny.
Defensive patterns

Strategy: validation

Validate before calling

// For a custom reader, guarantee bytesRemaining>0 before each expectSegment call.
// At the caller level, prefer a fully-buffered source so the parser's EOF loop works.
const bytes = new Uint8Array(await (await fetch(url)).arrayBuffer());
if (bytes.byteLength === 0) throw new Error('empty media source');
await parseMedia({src: bytes});

Try / catch

try {
  await parseMedia({src});
} catch (err) {
  if (err instanceof Error && err.message === 'has no bytes') {
    throw new Error('Parser asked to read past EOF; use a complete, buffered source.', {cause: err});
  }
  throw err;
}

Prevention

When it happens

Trigger: The parser is asked to read another element after the stream is fully consumed - typically a bug in the parse loop's termination condition, or a reader that signals EOF late. Also reachable if a Segment declared an unknown size but the underlying reader hit EOF and the loop did not break.

Common situations: Custom readers that misreport bytesRemaining, or malformed files where the Segment size is unknown (live-streamed) and EOF handling races with the loop.

Related errors


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