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
- If using a custom reader, ensure bytesRemaining() returns 0 exactly when EOF is reached and that parseMedia's loop observes it.
- Re-mux the file to give the Segment a concrete size.
- Use the built-in webReader or fetchReader with a complete Blob instead.
- 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
- Pass a complete Uint8Array/Blob rather than a streaming reader when possible.
- On custom readers, ensure bytesRemaining() is accurate and EOF is signalled cleanly.
- Give the Segment a concrete size by re-muxing live-streamed sources.
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
- Not enough bytes left to parse EBML - this should not happen
- Should not happen
- Unexpected type
- Expected av1 private data to be version 1
- Expected av1 private data to be version 1, got ${version}
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/12ecb11a0cad28e8.
Report an issue: GitHub.